diff --git a/Asteroid.cpp b/Asteroid.cpp index 61e25fc..cef480f 100644 --- a/Asteroid.cpp +++ b/Asteroid.cpp @@ -1,14 +1,50 @@ #include "Asteroid.h" Asteroid::Asteroid() { + + //set collision status + possible_collision = false; + // Check movementSpeed setting when star background is working movementSpeed = 363.0; // Create the asteroid // Can be exchanged with other functions to create other ships setMercuryPoints(); - - setPosition(-300, -200); + setPosition(200, 200); + + hitbox.setOrigin(0, 0); + num_hitbox_points = 6; + hitbox_points = new sf::Vector2f[num_hitbox_points]; + hitbox_points[0] = { -60.f, 0.f }; + hitbox_points[1] = { -30.f, 50.f }; + hitbox_points[2] = { 30.f, 50.f }; + hitbox_points[3] = { 60.f, 0.f }; + hitbox_points[4] = { 30.f, -50.f }; + hitbox_points[5] = { -30.f, -50.f }; + + hitbox.setPointCount(num_hitbox_points); + for (int i = 0; i < num_hitbox_points; ++i) + hitbox.setPoint(i, hitbox_points[i]); + + + hitbox.setPosition(getPosition().x, getPosition().y); + hitbox.setOutlineThickness(3.f); + hitbox.setFillColor(sf::Color::Transparent); + hitbox.setOutlineColor(sf::Color::Red); + hitbox.scale(0.35f, 0.35f); + + + + //circle anchor is at pi rads on circumference (instead of center) + // origin is thus offset by radius and height of gameobject to center around the object + hitradius.setOrigin(radius, radius); + hitradius.setPosition(getPosition().x, getPosition().y); + hitradius.setRadius(radius); + hitradius.setFillColor(sf::Color::Transparent); + hitradius.setOutlineColor(sf::Color::Green); + hitradius.setOutlineThickness(3.f); + } @@ -16,6 +52,12 @@ Asteroid::Asteroid() { // Sets points for the asteroid void Asteroid::setMercuryPoints() { + + Body.setOutlineThickness(3.f); + Body.setFillColor(sf::Color(184, 115, 52, 255)); + Body.setOrigin(0, 0); + Body.setPosition(0, 0); + Body.setPointCount(103); Body.setPoint(0, sf::Vector2f(0.f, 60.f)); Body.setPoint(1, sf::Vector2f(0.f, 60.f)); @@ -121,14 +163,27 @@ void Asteroid::setMercuryPoints() { Body.setPoint(101, sf::Vector2f(-6.f, 58.f)); Body.setPoint(102, sf::Vector2f(0.f, 58.f)); + + Body.setScale(0.35f, 0.35f); + +} - - Body.setOutlineThickness(3.f); - Body.setFillColor(sf::Color(184,115,52,255)); - Body.scale(0.3f, 0.3f); +void Asteroid::setHitboxPoints() { + hitbox.setPointCount(num_hitbox_points); + hitbox.setPoint(0, sf::Vector2f(-60.f, 0.f)); + hitbox.setPoint(1, sf::Vector2f(-30.f, 50.f)); + hitbox.setPoint(2, sf::Vector2f(30.f, 50.f)); + hitbox.setPoint(3, sf::Vector2f(60.f, 0.f)); + hitbox.setPoint(4, sf::Vector2f(30.f, -50.f)); + hitbox.setPoint(5, sf::Vector2f(-30.f, -50.f)); + + hitbox.setOutlineThickness(3.f); + hitbox.setFillColor(sf::Color::Transparent); + hitbox.setOutlineColor(sf::Color::Red); + hitbox.scale(0.35f, 0.35f); } @@ -136,7 +191,14 @@ void Asteroid::setMercuryPoints() { // Overridden draw function void Asteroid::draw(sf::RenderTarget& target, sf::RenderStates states)const { states.transform *= getTransform(); + + target.draw(hitradius); + if (possible_collision) { + target.draw(hitbox); + } + target.draw(Body, states); + } @@ -151,3 +213,21 @@ void Asteroid::update(sf::Time dt) { //void Asteroid::move(sf::Time dt) { // sf::Transformable::move(movement * dt.asSeconds()); //} + + +// getter function for Radius. There is no setter and this function returns a copy. +float Asteroid::getRadius() { + return radius; +} + +// sets the class boolean 'possible_collision' +void Asteroid::setPossibleCollision(bool possible) { + + if (possible) { + possible_collision = true; + } + + else { + possible_collision = false; + } +} \ No newline at end of file diff --git a/Asteroid.h b/Asteroid.h index bf5ca41..61fc621 100644 --- a/Asteroid.h +++ b/Asteroid.h @@ -12,7 +12,16 @@ class Asteroid : public GameObject { Asteroid(); void draw(sf::RenderTarget& target, sf::RenderStates states)const; void update(sf::Time dt); - //void move(sf::Time dt); + void move(sf::Time dt); + void setHitboxPoints(); + + + // prototype collision methods + float getRadius(); + void setPossibleCollision(bool possible); + + + private: @@ -21,6 +30,15 @@ class Asteroid : public GameObject { sf::ConvexShape Body; float movementSpeed; sf::Vector2f movement; - + + + // protoype collision data + float radius = 30; + sf::CircleShape hitradius; + bool possible_collision; + sf::ConvexShape hitbox; + int num_hitbox_points; + sf::Vector2f* hitbox_points; + }; #endif \ No newline at end of file diff --git a/PrototypeScene.cpp b/PrototypeScene.cpp index 091727c..35a5927 100644 --- a/PrototypeScene.cpp +++ b/PrototypeScene.cpp @@ -1,6 +1,7 @@ #include "PrototypeScene.h" #include "SystemClass.h" #include +#include @@ -87,6 +88,9 @@ void PrototypeScene::update(sf::Time dt) { alien->update(dt); asteroid.update(dt); sun->update(dt); + + collision_check(); + sf::Vector2f center = sun->getPosition(); for (int i = 0; i < 9; ++i) { @@ -119,4 +123,37 @@ void PrototypeScene::draw(sf::RenderWindow& window) { // Here so the system class can call something to know where the ship is for window.setCenter() sf::Vector2f PrototypeScene::getCenter(){ return ship.getPosition(); +} + + +// Prototype collision detection - will likely use a parent class array of pointers in the future +void PrototypeScene::collision_check() { + + // Step1: get position of objects + sf::Vector2f ship_pos = ship.getPosition(); + sf::Vector2f ast_pos = asteroid.getPosition(); + + // Step2: determine if objs are within eachothers outer hit radius + // if r1 + r2 >= ||ab||, where r1, r2 are objA and objB radius, and ||ab|| is the distance from pos_A to pos_B + + float rad_total = ship.getRadius() + asteroid.getRadius(); + + sf::Vector2f ab = ship_pos - ast_pos; + + // + float ab_length = ab.x * ab.x; + ab_length += (ab.y * ab.y); + ab_length = sqrt(ab_length); + + // If outtuer hit radius collides do more work + if (ab_length <= rad_total) { + // send signal to objects + // visual confirmation + ship.setPossibleCollision(true); + asteroid.setPossibleCollision(true); + } + else { + ship.setPossibleCollision(false); + asteroid.setPossibleCollision(false); + } } \ No newline at end of file diff --git a/PrototypeScene.h b/PrototypeScene.h index 3aabc3f..cfffea4 100644 --- a/PrototypeScene.h +++ b/PrototypeScene.h @@ -12,6 +12,9 @@ const int SYSTEMOBJECTS = 13; + + + class Background : public GameObject { public: Background(); @@ -35,16 +38,26 @@ class PrototypeScene : public Scene { void draw(sf::RenderWindow& window); sf::Vector2f getCenter(); + // prototype collision methods + void collision_check(); + bool hitbox_detection(Ship sh, Asteroid ast); + bool hitbox_detection_2(Ship sh, Asteroid ast); + bool hitbox_detection_3(Ship sh, Asteroid ast); + private: Background bg; - Ship ship; AlienShip* alien; Star* sun; Planet** planetarySystemObjects; + + // collision type objects + Ship ship; Asteroid asteroid; - sf::Vector2f center; + sf::Vector2f center; sf::View view; + bool debug = true; + }; #endif \ No newline at end of file diff --git a/Ship.cpp b/Ship.cpp index c2e97bd..6cbe95f 100644 --- a/Ship.cpp +++ b/Ship.cpp @@ -1,7 +1,12 @@ #include "Ship.h" +#include +#include Ship::Ship(): movementSpeed(SPEED), accelerating(false) { + + + // Create the ship // setBlueShipPoints(&body); // body.setOutlineThickness(3.f); @@ -13,11 +18,10 @@ Ship::Ship(): movementSpeed(SPEED), accelerating(false) { body.resize(7); // setBlueShipPoints(&hitbox); - // hitbox.setOutlineThickness(3.f); - // hitbox.setFillColor(sf::Color::Transparent); - // hitbox.setOutlineColor(sf::Color::Red); - // hitbox.scale(0.75f, 0.75f); - + + + + // Make main body of ship body[0].position = sf::Vector2f(0.f, 0.f); body[1].position = sf::Vector2f(-13.f, 0.f); @@ -93,10 +97,48 @@ Ship::Ship(): movementSpeed(SPEED), accelerating(false) { flame2[1].color = sf::Color(232, 48, 3, 255); flame2[2].color = sf::Color(232, 48, 3, 255); - // setScale(sf::Vector2f(4.f, 4.f)); - setPosition(0, 0); + // setScale(sf::Vector2f(4.f, 4.f)) + // note: position is relative to screen, origin is relative to object setRotation(180); - setOrigin(sf::Vector2f(0, 23)); + setOrigin(0,23); // 0 23 + setPosition(0, 0); + + + + // init collisions data + possible_collision = false; + + //circle anchor is at pi rads on circumference (instead of center) + // origin is thus offset by radius and height of gameobject to center around the object + hitradius.setRadius(radius); + hitradius.setOrigin(radius, radius); + hitradius.setPosition(0, 23); + hitradius.setFillColor(sf::Color::Transparent); + hitradius.setOutlineColor(sf::Color::Green); + hitradius.setOutlineThickness(3.f); + + num_hitbox_points = 4; + hitbox_points = new sf::Vector2f[num_hitbox_points]; + + hitbox_points[0] = { -10.f, -23.f }; + hitbox_points[1] = { 10.f, -23.f }; + hitbox_points[2] = { 10.f, 23.f }; + hitbox_points[3] = { -10.f, 23.f }; + + hitbox.setOrigin(0, 33); // 0 33 + hitbox.setPosition(0, 62); //0 62 + //hitbox.setRotation(180); + + // Make Ship hitbox + hitbox.setPointCount(num_hitbox_points); + hitbox.setPoint(0, hitbox_points[0]); + hitbox.setPoint(1, hitbox_points[1]); + hitbox.setPoint(2, hitbox_points[2]); + hitbox.setPoint(3, hitbox_points[3]); + + hitbox.setOutlineThickness(1.f); + hitbox.setFillColor(sf::Color::Transparent); + hitbox.setOutlineColor(sf::Color::Red); } @@ -169,22 +211,30 @@ void Ship::setBlueShipPoints(sf::ConvexShape * shape) { // Overridden draw function void Ship::draw(sf::RenderTarget& target, sf::RenderStates states)const{ states.transform *= getTransform(); - target.draw(body, states); + + target.draw(hitradius, states); + + + if (possible_collision) { + target.draw(hitbox, states); + } + + target.draw(body, states); + target.draw(thruster1, states); target.draw(thruster2, states); if (accelerating) { target.draw(flame1, states); target.draw(flame2, states); - } + } } - // Move or rotate the ship when keys are pressed -void Ship::update(sf::Time dt){ +void Ship::update(sf::Time dt) { accelerating = false; - if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left) || sf::Keyboard::isKeyPressed(sf::Keyboard::H)) { + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left) || sf::Keyboard::isKeyPressed(sf::Keyboard::H)) { rotate(-230.f * dt.asSeconds()); } @@ -198,17 +248,17 @@ void Ship::update(sf::Time dt){ } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up) || sf::Keyboard::isKeyPressed(sf::Keyboard::K)) { - movement += movementSpeed * dt.asSeconds() * sf::Vector2f(-sin(getRotation() * (3.1415 / 180)), - cos(getRotation() * (3.1415 / 180))); + movement += movementSpeed * dt.asSeconds() * sf::Vector2f(-sin(getRotation() * (3.1415 / 180)), + cos(getRotation() * (3.1415 / 180))); accelerating = true; } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down) || sf::Keyboard::isKeyPressed(sf::Keyboard::J)) { - movement -= movementSpeed * dt.asSeconds() * sf::Vector2f(-sin(getRotation() * (3.1415 / 180)), + movement -= movementSpeed * dt.asSeconds() * sf::Vector2f(-sin(getRotation() * (3.1415 / 180)), cos(getRotation() * (3.1415 / 180))); } - sf::Transformable::move(movement * dt.asSeconds()); + sf::Transformable::move(movement * dt.asSeconds()); } @@ -219,3 +269,22 @@ void Ship::update(sf::Time dt){ //void Ship::move(sf::Time dt){ // sf::Transformable::move(movement * dt.asSeconds()); //} + + +// getter function for Radius. There is no setter and this function returns a copy. +float Ship::getRadius() { + return radius; +} + + +// sets the class boolean 'possible_collision' +void Ship::setPossibleCollision(bool possible) { + + if (possible) { + possible_collision = true; + } + + else { + possible_collision = false; + } +} \ No newline at end of file diff --git a/Ship.h b/Ship.h index ae088c1..196d1f3 100644 --- a/Ship.h +++ b/Ship.h @@ -16,6 +16,12 @@ class Ship : public GameObject { void update(sf::Time dt); //void move(sf::Time dt); + // prototype collision methods + float getRadius(); + void setPossibleCollision(bool possible); + + + private: void setMercuryPoints(sf::ConvexShape * shape); void setBlueShipPoints(sf::ConvexShape * shape); @@ -26,9 +32,17 @@ class Ship : public GameObject { sf::VertexArray flame1; sf::VertexArray flame2; float movementSpeed; + bool accelerating; sf::Vector2f movement; + + // prototype collision data + float radius = 100.0; + sf::CircleShape hitradius; + bool possible_collision; + int num_hitbox_points; + sf::Vector2f* hitbox_points; sf::ConvexShape hitbox; - bool accelerating; + }; #endif \ No newline at end of file