Я пытаюсь создать базовый 2D-платформер, и я пытаюсь реализовать столкновение между спрайтом игрока и напольным спрайтом. Все компилируется, но игрок (которым управляет WASD без физики) продолжает сталкиваться с областью ниже пола.
Столкновение работает так, как должно, но сталкивается под объектом. Я почти уверен, что моя математика в порядке, поэтому я действительно не знаю проблемы. Спасибо!
(сюда не входит файл Floor.cpp (который реализует Collision.h), который может получить только свой спрайт. Каждый файл cpp имеет соответствующий файл .h, который работает.)
Вот код:
Collidable.h (интерфейс, который может возвращать координаты и ширину / высоту спрайта, и должен иметь возможность определять столкновение)
#pragma once
#include <SFML/Graphics.hpp>
#include <iostream>
using namespace sf;
class Collidable {
public:
float speed = 0.1;
float checkHoriz(float px, float py, float cx, float cy, float pH, float pW, float cH, float cW) {
if (cy > (py + pH)) {
return speed;
}
else if (py > (cy + cH)) {
return speed;
}else if (px > (cx + cW) + 0.1) {
return speed;
}
else if (cx > (px + pW) + 0.1) {
return speed;
}
else {
return 0;
}
}
float checkVert(float px, float py, float cx, float cy, float pH, float pW, float cH, float cW) {
if (px > (cx + cW)) {
return speed;
}
else if (cx > (px + pW)) {
return speed;
}else if (cy > (py + pH)+ 0.1) {
return speed;
}
else if (py > (cy + cH)+ 0.1) {
return speed;
}
else {
return 0;
}
}
float getH(Sprite h) {
float Height = h.getGlobalBounds().height;
return Height;
}
float getW(Sprite w) {
float Width = w.getGlobalBounds().width;
return Width;
}
float getX(Sprite hor) {
sf::Vector2f position1 = hor.getPosition();
float xPos = position1.x;
return xPos;
}
float getY(Sprite ver) {
sf::Vector2f position2 = ver.getPosition();
float yPos = position2.y;
return yPos;
}
};
Эти методы вызываются из player.cpp :
#pragma once
#include <SFML/Graphics.hpp>
#include <iostream>
#include <string>
#include "Player.h"
#include "Collidable.h"
#include "Floor.h"
using namespace sf;
Player::Player(float startX, float startY, Texture& text) {
position.x = startX;
position.y = startY;
playerSprite.setTexture(text);
playerSprite.setScale(0.5, 0.5);
playerSprite.setPosition(position);
}
Sprite Player::getSprite() {
return playerSprite;
}
FloatRect Player::getPosition() {
return playerSprite.getGlobalBounds();
};
void Player::moveLeft(Collidable p, Collidable f, Sprite sp, Sprite sf){
position.x -= p.checkHoriz(p.getX(sp), p.getY(sp), f.getX(sf), f.getY(sf), p.getH(sf), p.getW(sf), f.getH(sf), f.getW(sf));
}
void Player::moveRight(Collidable p, Collidable f, Sprite sp, Sprite sf){
position.x += p.checkHoriz(p.getX(sp), p.getY(sp), f.getX(sf), f.getY(sf), p.getH(sf), p.getW(sf), f.getH(sf), f.getW(sf));
}
void Player::moveUp(Collidable p, Collidable f, Sprite sp, Sprite sf){
position.y -= p.checkVert(p.getX(sp), p.getY(sp), f.getX(sf), f.getY(sf), p.getH(sf), p.getW(sf), f.getH(sf), f.getW(sf));
}
void Player::moveDown(Collidable p, Collidable f, Sprite sp, Sprite sf) {
position.y += p.checkVert(p.getX(sp), p.getY(sp), f.getX(sf), f.getY(sf), p.getH(sf), p.getW(sf), f.getH(sf), f.getW(sf));
}
void Player::update()
{
playerSprite.setPosition(position);
}
, который вызывается main () :
#include <SFML/Graphics.hpp>
#include "Player.h"
#include "Floor.h"
#include "Collidable.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include "Main.h"
using namespace sf;
float main(){
sf::RenderWindow window(sf::VideoMode(1000, 800), "Space Adventure");
sf::Texture playerText;
playerText.loadFromFile("Textures/IdleSpaceman.png");
sf::Texture floorText;
floorText.loadFromFile("Textures/FlrP.png");
std::vector<Collidable> collidables;
Player player(400, 300, playerText);
Floor floor(300, 500, floorText);
collidables.push_back(player);
collidables.push_back(floor);
//int objs = collidables.size();
while (window.isOpen()){
sf:Event event;
while (window.pollEvent(event)){
if (event.type == sf::Event::Closed){
window.close();
}
}
if (Keyboard::isKeyPressed(Keyboard::A)) {
player.moveLeft(player, floor, player.getSprite(), floor.getSprite());
}
if (Keyboard::isKeyPressed(Keyboard::D)) {
player.moveRight(player, floor, player.getSprite(), floor.getSprite());
}
if (Keyboard::isKeyPressed(Keyboard::W)) {
player.moveUp(player, floor, player.getSprite(), floor.getSprite());
}
if (Keyboard::isKeyPressed(Keyboard::S)) {
player.moveDown(player, floor, player.getSprite(), floor.getSprite());
}
if (Keyboard::isKeyPressed(Keyboard::P)) {
std::cout << "Player x position:" << player.getX(player.getSprite()) << std::endl;
std::cout << "Player y position:" << player.getY(player.getSprite()) << std::endl;
std::cout << "Player height:" << player.getH(player.getSprite()) << std::endl;
std::cout << "Player width:" << player.getW(player.getSprite()) << std::endl;
}
if (Keyboard::isKeyPressed(Keyboard::C)) {
std::cout << "Floor x position:" << floor.getX(floor.getSprite()) << std::endl;
std::cout << "Floor y position:" << floor.getY(floor.getSprite()) << std::endl;
std::cout << "Floor height position:" << floor.getH(floor.getSprite()) << std::endl;
std::cout << "Floor width position:" << floor.getW(floor.getSprite()) << std::endl;
}
player.update();
window.clear();
window.draw(player.getSprite());
window.draw(floor.getSprite());
window.display();
}
};