Collision class base
unknown
c_cpp
a year ago
9.6 kB
22
Indexable
Never
#pragma once #include <SFML/Graphics.hpp> #include <string> #include "Collider.h" #include <iostream> #include <cmath> #include "Tile.h" #include "Ray.h" #include "Tilemap.h" #include <vector> using namespace std; class Player { public: sf::Vector2f position; sf::Vector2f size; Collider collider; sf::Sprite sprite; int acceleration_max; bool left; bool right; bool onGround; float v; float speed; int f; float mass; sf::Text text_pos; sf::Font font; bool debug; bool up; bool running; sf::Vector2f screen_size; bool isJumping; float speed_original; bool isRunning; string lastError = "0x0"; Player() { this->position = sf::Vector2f(0, 0); this->speed = 3; this->speed_original = 3; this->v = 5; this->mass = 4; this->up = false; this->size = sf::Vector2f(50, 50); this->collider = Collider(this->position, this->size, true); this->acceleration_max = 1; this->left = false; this->right = false; this->onGround = false; this->font.loadFromFile("resources/fonts/RobotoMono-Light.ttf"); this->f = 0; this->text_pos.setFont(this->font); this->text_pos.setCharacterSize(12); this->text_pos.setFillColor(sf::Color::White); this->text_pos.setStyle(sf::Text::Bold); this->text_pos.setString(to_string((int)this->position.x) + "\n" + to_string((int)this->position.y)); this->debug = false; this->isRunning = false; } Player(sf::Vector2f position, sf::Vector2f velocity, sf::Vector2f acceleration, sf::Vector2f size, sf::Vector2f screen_size, Tilemap tilemap) { this->position = position; this->speed =3; this->speed_original = 3; this->v = 5; this->mass = 4; this->up = false; this->size = size; this->collider = Collider(this->position, this->size, true); this->acceleration_max = 1; this->left = false; this->right = false; this->onGround = false; this->font.loadFromFile("resources/fonts/RobotoMono-Light.ttf"); this->f = 0; this->text_pos.setFont(this->font); this->text_pos.setCharacterSize(12); this->text_pos.setFillColor(sf::Color::White); this->text_pos.setStyle(sf::Text::Bold); this->text_pos.setString(to_string((int)this->position.x) + "\n" + to_string((int)this->position.y)); this->debug = false; this->screen_size = screen_size; this->isRunning = false; } void update(sf::Vector2f mouse_pos, vector<Tile> close_tiles) { if (isRunning && onGround) { this->speed = this->speed_original * 2; } if (!isRunning && onGround) { this->speed = this->speed_original; } calculateMovement(); checkUp(close_tiles); checkGround(close_tiles); checkLeft(close_tiles); checkRight(close_tiles); if (!isJumping) { if (detectFloating(close_tiles)) { this->onGround = false; this->isJumping = false; } else { this->onGround = true; } } if (this->position.y > 500) { this->position.y = -500; } if (!onGround && isJumping) { this->mass = 4; f = (int)(mass * v); this->position += sf::Vector2f(0, -f); v-=.5f; if (v < -4) v = -4; } else if (!onGround && !isJumping) { this->mass = 3; v = -4; f = (int)(mass * v); this->position += sf::Vector2f(0, -f); } else if (onGround && !isJumping) { this->v = 5; this->mass = 0; } else if (onGround && isJumping) { } this->collider.update(sf::Vector2f(screen_size.x / 2, screen_size.y / 2)); if (this->debug) setDebugInfo(mouse_pos); } void checkGround(vector<Tile> close_tiles) { for (int i = 0; i < close_tiles.size(); i++) { if (close_tiles[i].collider.top.getGlobalBounds().intersects(this->collider.bottom.getGlobalBounds())) { this->onGround = true; this->isJumping = false; this->v = 5; this->mass = 0; correctYPos(close_tiles[i]); i = close_tiles.size(); return; } } } void checkLeft(vector<Tile> close_tiles) { for (int i = 0; i < close_tiles.size(); i++) { //if (passesCollisionTestLeft(close_tiles[i])) return; if (close_tiles[i].collider.right.getGlobalBounds().intersects(this->collider.left.getGlobalBounds())) { this->position += sf::Vector2f((getOverlapLeft(close_tiles[i])), 0); } } return; } void checkRight(vector<Tile> close_tiles) { for (int i = 0; i < close_tiles.size(); i++) { //if (passesCollisionTestRight(close_tiles[i])) return; if (close_tiles[i].collider.left.getGlobalBounds().intersects(this->collider.right.getGlobalBounds())) { this->position -= sf::Vector2f(getOverlapRight(close_tiles[i]), 0); //right = false; } } return; } void checkUp(vector<Tile> close_tiles) { for (int i = 0; i < close_tiles.size(); i++) { if (close_tiles[i].collider.bottom.getGlobalBounds().intersects(this->collider.top.getGlobalBounds())) { this->position += sf::Vector2f(0, getOverlapUp(close_tiles[i])); this->v = 0; return; } } } /*bool isCloseToWall(Tile close_tile) { if (close_tile.position_tilemap.x < this->position.x + 80 && close_tile.position_tilemap.x > this->position.x - 80) { return true; } return false; }*/ bool passesCollisionTestRight(Tile tile) { //check if at any point in the next frame moving right at speed, the player will be inside the tile //if so, return false //else return true if (this->position.x + this->speed < (tile.position.x - 20) && tile.isSolid) { return false; } else { tile.collider.top.setFillColor(sf::Color::Red); tile.collider.bottom.setFillColor(sf::Color::Red); tile.collider.left.setFillColor(sf::Color::Red); tile.collider.right.setFillColor(sf::Color::Red); } return false; } bool passesCollisionTestLeft(Tile tile) { //check if at any point in the next frame moving right at speed, the player will be inside the tile //if so, return false //else return true if (this->position.x - this->speed > tile.position.x + 20 && tile.isSolid) { return false; } return false; } bool detectFloating(vector<Tile> close_tiles) { bool isFloating = true; for (int i = 0; i < close_tiles.size(); i++) { if (this->collider.groundcheck.getGlobalBounds().intersects(close_tiles[i].collider.top.getGlobalBounds()) || this->collider.groundcheck_left.getGlobalBounds().intersects(close_tiles[i].collider.top.getGlobalBounds()) || this->collider.groundcheck_right.getGlobalBounds().intersects(close_tiles[i].collider.top.getGlobalBounds())) { isFloating = false; } else { // } } return isFloating; } void correctYPos(Tile tile) { float overlap = getOverlapBelow(tile); this->position += sf::Vector2f(0, -overlap); //this->collider.update(sf::Vector2f(screen_size.x / 2, screen_size.y / 2)); } float getOverlapBelow(Tile tile) { float overlap = 0; if (this->collider.bottom.getGlobalBounds().intersects(tile.collider.top.getGlobalBounds())) { overlap = this->collider.bottom.getGlobalBounds().height - (tile.collider.top.getGlobalBounds().top - this->collider.bottom.getGlobalBounds().top); } return overlap; } float getOverlapLeft(Tile tile) { float overlap = 0; if (this->collider.left.getGlobalBounds().intersects(tile.collider.right.getGlobalBounds())) { //overlap is the x distance between (tile.collider.pos.x + tile.collider.size.width/2) and (this->collider.pos.x + player.collider.size.width/2) float y = tile.collider.right.getPosition().x + ((int)tile.collider.right.getSize().x / 2); float x = this->collider.left.getPosition().x; overlap = (int)std::abs(x - y); } return overlap; } float getOverlapRight(Tile tile) { float overlap = 0; if (this->collider.right.getGlobalBounds().intersects(tile.collider.left.getGlobalBounds())) { overlap = this->collider.right.getGlobalBounds().width - (tile.collider.left.getGlobalBounds().left - this->collider.right.getGlobalBounds().left); } return overlap; } float getOverlapUp(Tile tile) { float overlap = 0; if (this->collider.top.getGlobalBounds().intersects(tile.collider.bottom.getGlobalBounds())) { overlap = this->collider.top.getGlobalBounds().height - (tile.collider.bottom.getGlobalBounds().top - this->collider.top.getGlobalBounds().top); } return overlap; } void calculateMovement() { if (this->left) this->position += sf::Vector2f(-speed, 0); else if (this->right) this->position += sf::Vector2f(speed, 0); //this->collider.update(sf::Vector2f(screen_size.x / 2, screen_size.y / 2)); } void draw(sf::RenderWindow& window) { window.draw(this->sprite); this->collider.draw(window); if (this->debug) window.draw(text_pos); } int distanceFromPlayer(Tile tile) { int dist = sqrt(pow((this->position.x - tile.position.x), 2) + pow((this->position.y - tile.position.y), 2)); } int isColliding(Collider& other) { return this->collider.isTopColliding(other); // 1 - top // 2 - bottom // 3 - left // 4 - right // 0 - no collision } void collide() { //this->position.y = 200; this->onGround = true; f = 0; mass = 5; v = 10; } void setDebugInfo(sf::Vector2f mouse_pos) { this->text_pos.setString( "player_pos: " + to_string((int)position.x) + ", " + to_string((int)position.y) + "\n" + "mouse_pos: " + to_string((int)mouse_pos.x) + ", " + to_string((int)mouse_pos.y) + "\n" + (onGround ? "On ground: True" : "On ground: False") + "\n" + "\nv: " + to_string(this->v) + "\n" + "m: " + to_string((int)this->mass) + "\n" + "f: " + to_string(this->f) + "\n" + "lastERR: " + lastError); text_pos.setPosition(sf::Vector2f(5, 5)); } };