140 lines
4.5 KiB
C++
140 lines
4.5 KiB
C++
#include "player.hpp"
|
|
#include <iostream>
|
|
using namespace std;
|
|
|
|
Player::Player()
|
|
: shape(sf::Vector2f(60.f, 60.f)),
|
|
speed(500.f),
|
|
velocityY(0.f),
|
|
jumpStrength(700.f),
|
|
onGround(true),
|
|
gravity(1500.f),
|
|
groundLevel(1040.f),
|
|
facingRight(true),
|
|
runFrames(),
|
|
idleFrame(),
|
|
sprite(),
|
|
currentFrame(0),
|
|
animationTimer(0.f),
|
|
animationSpeed(0.1f),
|
|
isMoving(false)
|
|
{
|
|
shape.setFillColor(sf::Color::Green);
|
|
shape.setPosition(50.f, groundLevel);
|
|
|
|
loadIdleFrame();
|
|
loadRunAnimation();
|
|
|
|
sprite.setTexture(idleFrame);
|
|
sprite.setOrigin(idleFrame.getSize().x / 2.f, idleFrame.getSize().y / 2.f);
|
|
|
|
float scaleX = shape.getSize().x / idleFrame.getSize().x;
|
|
float scaleY = shape.getSize().y / idleFrame.getSize().y;
|
|
|
|
// Початкове віддзеркалення: PNG дивиться вліво, потрібно вправо
|
|
sprite.setScale(-scaleX, scaleY);
|
|
|
|
sprite.setPosition(
|
|
shape.getPosition().x + shape.getSize().x / 2.f,
|
|
shape.getPosition().y + shape.getSize().y / 2.f
|
|
);
|
|
}
|
|
|
|
void Player::loadIdleFrame() {
|
|
if (!idleFrame.loadFromFile("img/FA_PENGUIN_Idle_000.png")) {
|
|
cout << "Cannot load idle frame\n";
|
|
}
|
|
}
|
|
|
|
void Player::loadRunAnimation() {
|
|
runFrames.clear();
|
|
for (size_t i = 0; i < 10; ++i) { // припустимо 10 кадрів
|
|
sf::Texture tex;
|
|
string filename = "img/04-Run/FA_PENGUIN_Run_00" + to_string(i) + ".png";
|
|
if (!tex.loadFromFile(filename)) {
|
|
cout << "Cannot load " << filename << "\n";
|
|
} else {
|
|
runFrames.push_back(tex);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player::update(float deltaTime, const std::vector<Platform>& platforms) {
|
|
float moveX = 0.f;
|
|
isMoving = false;
|
|
|
|
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
|
|
moveX -= speed * deltaTime;
|
|
facingRight = false;
|
|
isMoving = true;
|
|
}
|
|
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
|
|
moveX += speed * deltaTime;
|
|
facingRight = true;
|
|
isMoving = true;
|
|
}
|
|
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W) && onGround)
|
|
velocityY = -jumpStrength;
|
|
|
|
velocityY += gravity * deltaTime;
|
|
shape.move(moveX, 0.f);
|
|
shape.move(0.f, velocityY * deltaTime);
|
|
|
|
// Земля
|
|
if (shape.getPosition().y + shape.getSize().y >= groundLevel) {
|
|
shape.setPosition(shape.getPosition().x, groundLevel - shape.getSize().y);
|
|
velocityY = 0.f;
|
|
onGround = true;
|
|
} else onGround = false;
|
|
|
|
// Колізії з платформами
|
|
for (const auto& platform : platforms) {
|
|
sf::FloatRect playerBounds = shape.getGlobalBounds();
|
|
sf::FloatRect platBounds = platform.getBounds();
|
|
if (playerBounds.intersects(platBounds)) {
|
|
if (playerBounds.top + playerBounds.height <= platBounds.top + 20.f) {
|
|
shape.setPosition(shape.getPosition().x, platBounds.top - shape.getSize().y);
|
|
velocityY = 0.f;
|
|
onGround = true;
|
|
} else if (playerBounds.top > platBounds.top) {
|
|
shape.setPosition(shape.getPosition().x, platBounds.top + platBounds.height);
|
|
velocityY = 0.f;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Межі екрану
|
|
if (shape.getPosition().x < 0.f) shape.setPosition(0.f, shape.getPosition().y);
|
|
if (shape.getPosition().x + shape.getSize().x > 1925.f)
|
|
shape.setPosition(1925.f - shape.getSize().x, shape.getPosition().y);
|
|
|
|
// Анімація
|
|
animationTimer += deltaTime;
|
|
if (isMoving && !runFrames.empty()) {
|
|
if (animationTimer >= animationSpeed) {
|
|
animationTimer = 0.f;
|
|
currentFrame = (currentFrame + 1) % runFrames.size();
|
|
sprite.setTexture(runFrames[currentFrame]);
|
|
}
|
|
} else {
|
|
sprite.setTexture(idleFrame);
|
|
}
|
|
|
|
// Центруємо спрайт по хітбоксу
|
|
sprite.setOrigin(sprite.getTexture()->getSize().x / 2.f,
|
|
sprite.getTexture()->getSize().y / 2.f);
|
|
|
|
sprite.setPosition(shape.getPosition().x + shape.getSize().x / 2.f,
|
|
shape.getPosition().y + shape.getSize().y / 2.f);
|
|
|
|
float scaleX = shape.getSize().x / sprite.getTexture()->getSize().x;
|
|
float scaleY = shape.getSize().y / sprite.getTexture()->getSize().y;
|
|
|
|
// Віддзеркалення за напрямком погляду
|
|
sprite.setScale(facingRight ? -scaleX : scaleX, scaleY);
|
|
}
|
|
|
|
void Player::draw(sf::RenderWindow& window) {
|
|
window.draw(sprite);
|
|
}
|
|
|