2d_patformer/game.cpp
2026-01-09 10:21:48 +00:00

159 lines
5.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <SFML/Graphics.hpp>
#include "vokzal.hpp"
#include "enemy.hpp"
#include <vector>
#include <iostream>
using namespace std;
int main() {
// Завантаження фону
sf::Texture backgroundTexture;
if (!backgroundTexture.loadFromFile("img/background.png")) {
cout << "ERROR: Cannot load background.png\n";
}
sf::Sprite backgroundSprite;
backgroundSprite.setTexture(backgroundTexture);
float scaleX = 1950.f / backgroundTexture.getSize().x;
float scaleY = 1200.f / backgroundTexture.getSize().y;
backgroundSprite.setScale(scaleX, scaleY);
sf::RenderWindow window(sf::VideoMode(1950, 1200), "2D Platformer");
window.setFramerateLimit(65);
// Платформи
vector<Platform> platforms;
platforms.push_back(Platform(299.f, 900.f, 200.f, 40.f));
platforms.push_back(Platform(700.f, 725.f, 200.f, 40.f));
platforms.push_back(Platform(1300.f, 700.f, 300.f, 50.f));
platforms.push_back(Platform(400.f, 600.f, 250.f, 30.f));
platforms.push_back(Platform(700.f, 900.f, 400.f, 30.f));
Platform ground(100.f, 1050.f, 300.f, 50.f);
// Гравець
Player player;
// Вороги
vector<Enemy> enemies;
for (auto& platform : platforms) {
float left = platform.getBounds().left;
float top = platform.getBounds().top;
float width = platform.getBounds().width;
enemies.push_back(Enemy(left + 10.f, top - 50.f, left, left + width));
}
// Кулі
vector<Bullet> bullets;
sf::Clock fireClock;
float fireCooldown = 0.3f;
sf::Clock gameClock;
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
window.close();
}
float deltaTime = gameClock.restart().asSeconds();
// Рух гравця
player.update(deltaTime, platforms);
// Створення кулі при натиску пробілу
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space) &&
fireClock.getElapsedTime().asSeconds() >= fireCooldown)
{
fireClock.restart();
sf::Vector2f playerPos(
player.getShape().getPosition().x + player.getShape().getSize().x / 2,
player.getShape().getPosition().y + player.getShape().getSize().y / 2
);
bullets.push_back(Bullet(playerPos, player.isFacingRight()));
}
// Оновлення і видалення куль
for (auto it = bullets.begin(); it != bullets.end(); ) {
it->update(deltaTime);
if (it->isOffScreen() || it->collidesWithPlatform(platforms)) {
it = bullets.erase(it);
} else ++it;
}
// Оновлення ворогів (агро на гравця)
sf::Vector2f playerPosVec(player.getShape().getPosition().x, player.getShape().getPosition().y);
for (auto& enemy : enemies) {
float playerBottom = player.getShape().getPosition().y + player.getShape().getSize().y;
float platformY = enemy.getPlatformY();
float tolerance = 10.f;
// якщо гравець на тій же платформі
if (playerBottom >= platformY - tolerance && playerBottom <= platformY + tolerance) {
enemy.setAggro(true);
} else {
enemy.setAggro(false);
}
enemy.update(deltaTime, playerPosVec);
}
// Колізія куль з ворогами
for (auto it = bullets.begin(); it != bullets.end(); ) {
bool bulletRemoved = false;
for (auto enemyIt = enemies.begin(); enemyIt != enemies.end(); ++enemyIt) {
if (it->getBounds().intersects(enemyIt->getBounds())) {
it = bullets.erase(it);
enemies.erase(enemyIt);
bulletRemoved = true;
break;
}
}
if (!bulletRemoved) ++it;
}
// Кінець гри, якщо всі вороги вбиті
if (enemies.empty()) {
cout << "Вітаємо! Ви перемогли всіх ворогів!\n";
window.close();
}
// Колізія ворогів з гравцем
bool playerHit = false;
for (auto& enemy : enemies) {
if (enemy.getBounds().intersects(sf::FloatRect(player.getShape().getPosition(), player.getShape().getSize()))) {
playerHit = true;
break;
}
}
// Ресет гри
if (playerHit) {
player.setPosition(sf::Vector2f(50.f, 1040.f));
player.setVelocityY(0.f);
player.setOnGround(true);
enemies.clear();
for (auto& platform : platforms) {
float left = platform.getBounds().left;
float top = platform.getBounds().top;
float width = platform.getBounds().width;
enemies.push_back(Enemy(left + 10.f, top - 50.f, left, left + width));
}
bullets.clear();
}
// Відмалювання
window.clear(sf::Color::Black);
window.draw(backgroundSprite);
for (auto& platform : platforms) platform.draw(window);
ground.draw(window);
player.draw(window);
for (auto& enemy : enemies) enemy.draw(window);
for (auto& bullet : bullets) bullet.draw(window);
window.display();
}
return 0;
}