Collision class base
unknown
c_cpp
2 years ago
9.6 kB
29
Indexable
#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));
}
};
Editor is loading...