commit e7d0002ca71ccda968a023ad4b1de9621b658408 Author: bMorgan01 Date: Fri Oct 9 11:03:52 2020 -0600 init commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5f79aae --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.idea/ +bin/ +cmake-build-debug/ +include/ +lib/ \ No newline at end of file diff --git a/Asteroid.h b/Asteroid.h new file mode 100644 index 0000000..2898f98 --- /dev/null +++ b/Asteroid.h @@ -0,0 +1,35 @@ +// +// Created by benmo on 9/28/2020. +// + +#ifndef SFML_TEMPLATE_ASTEROID_H +#define SFML_TEMPLATE_ASTEROID_H + +#include "Entity.h" + +class Asteroid : public Entity { +public: + Asteroid(int health, int points, const sf::Texture &texture, float scale, float xPos, float yPos, float velocity, float direction) : Entity(health, points, texture, scale, xPos, yPos, velocity, direction) { + size = health; + type = "asteroid"; + } + + int getSize() const { + return size; + } + + void hit(vector &animations, Sound &sound, Texture &explosion, default_random_engine &gen) { + uniform_int_distribution angle(0, 359); + animations.push_back(new MySprite(explosion, getSize()*65, getXPos(), getYPos(), 0, angle(gen))); + animations[animations.size() - 1]->makeAnimated(5, 5, 0.01,23); + + sound.setVolume(100.0/((4-size)/1.5)); + sound.play(); + } + +private: + int size; +}; + + +#endif //SFML_TEMPLATE_ASTEROID_H diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a2da041 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,58 @@ +cmake_minimum_required(VERSION 3.12) +project(SFML_Template) + +include_directories(include) +link_directories(lib) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY bin) + +add_executable(SFML_Template main.cpp Game.h Menu.h MySprite.h Ship.h Entity.h Asteroid.h Collision.cpp Collision.h) +target_link_libraries(SFML_Template sfml-audio sfml-graphics sfml-system sfml-window sfml-network sfml-main) + +# Copy single files +macro(resource_files files) + foreach(file ${files}) + message(STATUS " Copying resource ${file} to ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") + file(COPY ${file} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + endforeach() +endmacro() + +# Copy full directories +macro(resource_dirs dirs) + foreach(dir ${dirs}) + # Replace / at the end of the path (copy dir content VS copy dir) + string(REGEX REPLACE "/+$" "" dirclean "${dir}") + file(GLOB files "${dirclean}/*.dll") + message(STATUS "Copying directory ${dirclean}") + foreach(file ${files}) + resource_files(${file}) + endforeach() + message(STATUS "Done copying directory ${dirclean}") + endforeach() +endmacro() + +# Copy single files +macro(data_files files) + foreach(file ${files}) + message(STATUS " Copying resource ${file} to ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/data") + file(COPY ${file} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/data) + endforeach() +endmacro() + +# Copy full directories +macro(data_dirs dirs) + foreach(dir ${dirs}) + # Replace / at the end of the path (copy dir content VS copy dir) + string(REGEX REPLACE "/+$" "" dirclean "${dir}") + file(GLOB files "${dirclean}/*") + message(STATUS "Copying directory ${dirclean}") + foreach(file ${files}) + data_files(${file}) + endforeach() + message(STATUS "Done copying directory ${dirclean}") + endforeach() +endmacro() + +resource_dirs(bin/) +data_dirs(data/) \ No newline at end of file diff --git a/Collision.cpp b/Collision.cpp new file mode 100644 index 0000000..ce6cbc3 --- /dev/null +++ b/Collision.cpp @@ -0,0 +1,190 @@ +/* + * File: collision.cpp + * Author: Nick (original version), ahnonay (SFML2 compatibility) + */ + +#include +#include "Collision.h" + +namespace Collision +{ + class BitmaskManager + { + public: + ~BitmaskManager() { + std::map::const_iterator end = Bitmasks.end(); + for (std::map::const_iterator iter = Bitmasks.begin(); iter!=end; iter++) + delete [] iter->second; + } + + sf::Uint8 GetPixel (const sf::Uint8* mask, const sf::Texture* tex, unsigned int x, unsigned int y) { + if (x>tex->getSize().x||y>tex->getSize().y) + return 0; + + return mask[x+y*tex->getSize().x]; + } + + sf::Uint8* GetMask (const sf::Texture* tex) { + sf::Uint8* mask; + std::map::iterator pair = Bitmasks.find(tex); + if (pair==Bitmasks.end()) + { + sf::Image img = tex->copyToImage(); + mask = CreateMask (tex, img); + } + else + mask = pair->second; + + return mask; + } + + sf::Uint8* CreateMask (const sf::Texture* tex, const sf::Image& img) { + sf::Uint8* mask = new sf::Uint8[tex->getSize().y*tex->getSize().x]; + + for (unsigned int y = 0; ygetSize().y; y++) + { + for (unsigned int x = 0; xgetSize().x; x++) + mask[x+y*tex->getSize().x] = img.getPixel(x,y).a; + } + + Bitmasks.insert(std::pair(tex,mask)); + + return mask; + } + private: + std::map Bitmasks; + }; + + BitmaskManager Bitmasks; + + bool PixelPerfectTest(const sf::Sprite& Object1, const sf::Sprite& Object2, sf::Uint8 AlphaLimit) { + sf::FloatRect Intersection; + if (Object1.getGlobalBounds().intersects(Object2.getGlobalBounds(), Intersection)) { + sf::IntRect O1SubRect = Object1.getTextureRect(); + sf::IntRect O2SubRect = Object2.getTextureRect(); + + sf::Uint8* mask1 = Bitmasks.GetMask(Object1.getTexture()); + sf::Uint8* mask2 = Bitmasks.GetMask(Object2.getTexture()); + + // Loop through our pixels + for (int i = Intersection.left; i < Intersection.left+Intersection.width; i++) { + for (int j = Intersection.top; j < Intersection.top+Intersection.height; j++) { + + sf::Vector2f o1v = Object1.getInverseTransform().transformPoint(i, j); + sf::Vector2f o2v = Object2.getInverseTransform().transformPoint(i, j); + + // Make sure pixels fall within the sprite's subrect + if (o1v.x > 0 && o1v.y > 0 && o2v.x > 0 && o2v.y > 0 && + o1v.x < O1SubRect.width && o1v.y < O1SubRect.height && + o2v.x < O2SubRect.width && o2v.y < O2SubRect.height) { + + if (Bitmasks.GetPixel(mask1, Object1.getTexture(), (int)(o1v.x)+O1SubRect.left, (int)(o1v.y)+O1SubRect.top) > AlphaLimit && + Bitmasks.GetPixel(mask2, Object2.getTexture(), (int)(o2v.x)+O2SubRect.left, (int)(o2v.y)+O2SubRect.top) > AlphaLimit) + return true; + + } + } + } + } + return false; + } + + bool CreateTextureAndBitmask(sf::Texture &LoadInto, const std::string& Filename) + { + sf::Image img; + if (!img.loadFromFile(Filename)) + return false; + if (!LoadInto.loadFromImage(img)) + return false; + + Bitmasks.CreateMask(&LoadInto, img); + return true; + } + + sf::Vector2f GetSpriteCenter (const sf::Sprite& Object) + { + sf::FloatRect AABB = Object.getGlobalBounds(); + return sf::Vector2f (AABB.left+AABB.width/2.f, AABB.top+AABB.height/2.f); + } + + sf::Vector2f GetSpriteSize (const sf::Sprite& Object) + { + sf::IntRect OriginalSize = Object.getTextureRect(); + sf::Vector2f Scale = Object.getScale(); + return sf::Vector2f (OriginalSize.width*Scale.x, OriginalSize.height*Scale.y); + } + + bool CircleTest(const sf::Sprite& Object1, const sf::Sprite& Object2) { + sf::Vector2f Obj1Size = GetSpriteSize(Object1); + sf::Vector2f Obj2Size = GetSpriteSize(Object2); + float Radius1 = (Obj1Size.x + Obj1Size.y) / 4; + float Radius2 = (Obj2Size.x + Obj2Size.y) / 4; + + sf::Vector2f Distance = GetSpriteCenter(Object1)-GetSpriteCenter(Object2); + + return (Distance.x * Distance.x + Distance.y * Distance.y <= (Radius1 + Radius2) * (Radius1 + Radius2)); + } + + class OrientedBoundingBox // Used in the BoundingBoxTest + { + public: + OrientedBoundingBox (const sf::Sprite& Object) // Calculate the four points of the OBB from a transformed (scaled, rotated...) sprite + { + sf::Transform trans = Object.getTransform(); + sf::IntRect local = Object.getTextureRect(); + Points[0] = trans.transformPoint(0.f, 0.f); + Points[1] = trans.transformPoint(local.width, 0.f); + Points[2] = trans.transformPoint(local.width, local.height); + Points[3] = trans.transformPoint(0.f, local.height); + } + + sf::Vector2f Points[4]; + + void ProjectOntoAxis (const sf::Vector2f& Axis, float& Min, float& Max) // Project all four points of the OBB onto the given axis and return the dotproducts of the two outermost points + { + Min = (Points[0].x*Axis.x+Points[0].y*Axis.y); + Max = Min; + for (int j = 1; j<4; j++) + { + float Projection = (Points[j].x*Axis.x+Points[j].y*Axis.y); + + if (ProjectionMax) + Max=Projection; + } + } + }; + + bool BoundingBoxTest(const sf::Sprite& Object1, const sf::Sprite& Object2) { + OrientedBoundingBox OBB1 (Object1); + OrientedBoundingBox OBB2 (Object2); + + // Create the four distinct axes that are perpendicular to the edges of the two rectangles + sf::Vector2f Axes[4] = { + sf::Vector2f (OBB1.Points[1].x-OBB1.Points[0].x, + OBB1.Points[1].y-OBB1.Points[0].y), + sf::Vector2f (OBB1.Points[1].x-OBB1.Points[2].x, + OBB1.Points[1].y-OBB1.Points[2].y), + sf::Vector2f (OBB2.Points[0].x-OBB2.Points[3].x, + OBB2.Points[0].y-OBB2.Points[3].y), + sf::Vector2f (OBB2.Points[0].x-OBB2.Points[1].x, + OBB2.Points[0].y-OBB2.Points[1].y) + }; + + for (int i = 0; i<4; i++) // For each axis... + { + float MinOBB1, MaxOBB1, MinOBB2, MaxOBB2; + + // ... project the points of both OBBs onto the axis ... + OBB1.ProjectOntoAxis(Axes[i], MinOBB1, MaxOBB1); + OBB2.ProjectOntoAxis(Axes[i], MinOBB2, MaxOBB2); + + // ... and check whether the outermost projected points of both OBBs overlap. + // If this is not the case, the Separating Axis Theorem states that there can be no collision between the rectangles + if (!((MinOBB2<=MaxOBB1)&&(MaxOBB2>=MinOBB1))) + return false; + } + return true; + } +} \ No newline at end of file diff --git a/Collision.h b/Collision.h new file mode 100644 index 0000000..dfb3e53 --- /dev/null +++ b/Collision.h @@ -0,0 +1,77 @@ +/* + * File: collision.h + * Authors: Nick Koirala (original version), ahnonay (SFML2 compatibility) + * + * Collision Detection and handling class + * For SFML2. + + Notice from the original version: + + (c) 2009 - LittleMonkey Ltd + + This software is provided 'as-is', without any express or + implied warranty. In no event will the authors be held + liable for any damages arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; + you must not claim that you wrote the original software. + If you use this software in a product, an acknowledgment + in the product documentation would be appreciated but + is not required. + + 2. Altered source versions must be plainly marked as such, + and must not be misrepresented as being the original software. + + 3. This notice may not be removed or altered from any + source distribution. + + * + * Created on 30 January 2009, 11:02 + */ + +#ifndef SFML_TEMPLATE_COLLISION_H +#define SFML_TEMPLATE_COLLISION_H + +#include + +namespace Collision { + ////// + /// Test for a collision between two sprites by comparing the alpha values of overlapping pixels + /// Supports scaling and rotation + /// AlphaLimit: The threshold at which a pixel becomes "solid". If AlphaLimit is 127, a pixel with + /// alpha value 128 will cause a collision and a pixel with alpha value 126 will not. + /// + /// This functions creates bitmasks of the textures of the two sprites by + /// downloading the textures from the graphics card to memory -> SLOW! + /// You can avoid this by using the "CreateTextureAndBitmask" function + ////// + bool PixelPerfectTest(const sf::Sprite& Object1 ,const sf::Sprite& Object2, sf::Uint8 AlphaLimit = 0); + + ////// + /// Replaces Texture::loadFromFile + /// Load an imagefile into the given texture and create a bitmask for it + /// This is much faster than creating the bitmask for a texture on the first run of "PixelPerfectTest" + /// + /// The function returns false if the file could not be opened for some reason + ////// + bool CreateTextureAndBitmask(sf::Texture &LoadInto, const std::string& Filename); + + ////// + /// Test for collision using circle collision dection + /// Radius is averaged from the dimensions of the sprite so + /// roughly circular objects will be much more accurate + ////// + bool CircleTest(const sf::Sprite& Object1, const sf::Sprite& Object2); + + ////// + /// Test for bounding box collision using the Separating Axis Theorem + /// Supports scaling and rotation + ////// + bool BoundingBoxTest(const sf::Sprite& Object1, const sf::Sprite& Object2); +} + +#endif //SFML_TEMPLATE_COLLISION_H diff --git a/Entity.h b/Entity.h new file mode 100644 index 0000000..72e3ffe --- /dev/null +++ b/Entity.h @@ -0,0 +1,39 @@ +// +// Created by benmo on 9/28/2020. +// + +#ifndef SFML_TEMPLATE_ENTITY_H +#define SFML_TEMPLATE_ENTITY_H + +class Entity : public MySprite { +public: + Entity(int health, int points, const sf::Texture &texture, float scale, float xPos, float yPos, float velocity, float direction) : MySprite(texture, scale, xPos, yPos, velocity, direction) { + this->health = health; + this->points = points; + } + + int getHealth() const { + return health; + } + + void setHealth(int health) { + this->health = health; + } + + void hit() {}; + + string getType() { + return type; + } + + int getPoints() const { + return points; + } +protected: + int health, points; + + string type = "entity"; +}; + + +#endif //SFML_TEMPLATE_ENTITY_H diff --git a/Game.h b/Game.h new file mode 100644 index 0000000..50f3b69 --- /dev/null +++ b/Game.h @@ -0,0 +1,385 @@ +class Game { +public: + int result; + + Game() { + result = init(); + } +private: + bool ended = false; + + int init() { + // display "Hello, World!" -- this still appears in our Run terminal as before + cout << "Hello, World!" << endl; + + default_random_engine gen(random_device{}()); + Clock fireClock, spawnClock, shieldTimer; + + // create a RenderWindow object + // specify the size to be 640x640 + // set the title to be "SFML Example Window" + RenderWindow window(VideoMode(1240, 640), "Asteroids"); + window.setFramerateLimit(30); + window.setPosition(sf::Vector2i(window.getPosition().x, window.getPosition().y - 50)); + + //******************************************** + // GRAPHICS + //******************************************** + Texture ship; + ship.loadFromFile("data\\Ship.png"); + + Texture shield; + shield.loadFromFile("data\\bubble.png"); + + Texture background; + background.loadFromFile("data\\back.png"); + + Texture blueLaser; + Collision::CreateTextureAndBitmask(blueLaser, "data\\blue.png"); + + Texture explosion; + explosion.loadFromFile("data\\explodeSheet.png"); + + vector < Texture * > largeAsteroids; + for (int i = 1; i <= 7; i++) { + largeAsteroids.push_back(new Texture); + Collision::CreateTextureAndBitmask(*largeAsteroids[largeAsteroids.size() - 1], + "data\\Asteroids\\(" + to_string(i) + ").png"); + } + + vector < Texture * > mediumAsteroids; + for (int i = 8; i <= 17; i++) { + mediumAsteroids.push_back(new Texture); + Collision::CreateTextureAndBitmask(*mediumAsteroids[mediumAsteroids.size() - 1], + "data\\Asteroids\\(" + to_string(i) + ").png"); + } + + vector < Texture * > smallAsteroids; + for (int i = 18; i <= 23; i++) { + smallAsteroids.push_back(new Texture); + Collision::CreateTextureAndBitmask(*smallAsteroids[smallAsteroids.size() - 1], + "data\\Asteroids\\(" + to_string(i) + ").png"); + } + + //******************************************** + // SOUNDS + //******************************************** + + Sound pew; + SoundBuffer pewBuff; + pewBuff.loadFromFile("data\\Sounds\\pew.wav"); + pew.setBuffer(pewBuff); + pew.setVolume(25); + + Sound enemyBoom; + SoundBuffer enemyBoomBuff; + enemyBoomBuff.loadFromFile("data\\Sounds\\explosions.wav"); + enemyBoom.setBuffer(enemyBoomBuff); + + Sound newLife; + SoundBuffer newLifeBuff; + newLifeBuff.loadFromFile("data\\Sounds\\pling.wav"); + newLife.setBuffer(newLifeBuff); + + //******************************************** + // Text + //******************************************** + + Text score; + Font f; + score.setFillColor(Color::White); + score.setPosition(10, 10); + f.loadFromFile("data\\Fonts\\arial.ttf"); + score.setFont(f); + score.setString("Score: 0"); + score.setCharacterSize(20); + + Text destroyed; + Font sk; + destroyed.setFillColor(Color::White); + sk.loadFromFile("data\\Fonts\\Sk.ttf"); + destroyed.setFont(sk); + destroyed.setCharacterSize(70); + destroyed.setString("Destroyed"); + destroyed.setOrigin(destroyed.getGlobalBounds().width/2.0, destroyed.getGlobalBounds().height/2.0); + destroyed.setPosition(window.getSize().x/2.0, window.getSize().y/3.0); + + Text pressEnter; + Font monkirta; + pressEnter.setFillColor(Color::White); + monkirta.loadFromFile("data\\Fonts\\Monkirta Pursuit NC.ttf"); + pressEnter.setFont(monkirta); + pressEnter.setCharacterSize(20); + pressEnter.setString("Press ENTER to return to the menu..."); + pressEnter.setOrigin(pressEnter.getGlobalBounds().width/2.0, pressEnter.getGlobalBounds().height/2.0); + pressEnter.setPosition(window.getSize().x/2.0, window.getSize().y/2.25); + + //******************************************** + // Resource loading above here + //******************************************** + + vector < MySprite * > projectiles; + vector < MySprite * > animations; + vector < Entity * > enemies; + vector < Drawable * > gui; + vector < Drawable * > lost; + + lost.push_back(&destroyed); + lost.push_back(&pressEnter); + + gui.push_back(new MySprite(background, 100, window.getSize().x / 2, window.getSize().y / 2, 0, 0)); + Ship player(ship, 30, window.getSize().x / 2, window.getSize().y / 2, 0, 0); + player.setMaxVelocity(15); + player.setMinVelocity(-7); + player.setEdgeBehavior(MySprite::EdgeBehavior::LOOP); + player.setShield(true, &shield, 12, &shieldTimer); + + for (int i = 0; i < player.getLives(); i++) + gui.push_back(new MySprite(ship, 20, window.getSize().x - (i * 40 + 25), 25, 0, 270)); + + gui.push_back(&score); + + // while our window is open, keep it open + // this is our draw loop + while (window.isOpen()) { + window.clear(Color::Black); // clear the contents of the old frame + // by setting the window to black + + if (shieldTimer.getElapsedTime().asSeconds() > 5) { + player.setShield(false); + } + + //**************************************** + // Handle keypresses below here + //**************************************** + + if ((Keyboard::isKeyPressed(Keyboard::Up) || Keyboard::isKeyPressed(Keyboard::W))) player.accelerate(0.5); + if ((Keyboard::isKeyPressed(Keyboard::Down) || Keyboard::isKeyPressed(Keyboard::S))) player.accelerate(-.5); + if ((Keyboard::isKeyPressed(Keyboard::Right) || Keyboard::isKeyPressed(Keyboard::D))) player.turn(10); + if ((Keyboard::isKeyPressed(Keyboard::Left) || Keyboard::isKeyPressed(Keyboard::A))) player.turn(-10); + if (Keyboard::isKeyPressed(Keyboard::Space) && fireClock.getElapsedTime().asSeconds() > 0.4) { + player.shoot(&projectiles, pew, blueLaser, 0.3, player.getPosition().x, player.getPosition().y, 20, + player.getDirection()); + fireClock.restart(); + } + if (Keyboard::isKeyPressed(Keyboard::Enter) && ended) return 0; + + //**************************************** + // Handle keypresses above here + //**************************************** + + //**************************************** + // Spawn cycle below here + //**************************************** + + uniform_int_distribution stroidChance(1, 4), stroidSize(1, 3), + smallTexture(0, smallAsteroids.size() - 1), + mediumTexture(0, mediumAsteroids.size() - 1), + largeTexture(0, largeAsteroids.size() - 1), side(1, 4), + xPos(0, window.getSize().x), yPos(0, window.getSize().y), + scale(70, 110), scaleLarge(65, 85); + + uniform_real_distribution velocity(0.5, 4); + + if (spawnClock.getElapsedTime().asSeconds() >= 0.10) { //spawn chances every .1 sec + if (stroidChance(gen) == 1) { //stroid spawns happen approx. every half sec + uniform_int_distribution angle; + int x = 0, y = 0, s = side(gen); + switch (s) { //decide which side of window to spawn stroid + case 1: //top + x = xPos(gen); //get random xPos + if (x <= window.getSize().x / + 2) { //if on left half of window (calculate angle to point towards window) + angle = uniform_int_distribution( + 285 - ((double) x) / (window.getSize().x / 2.0) * 75, 330); + } else { //else + angle = uniform_int_distribution(210, 330 - + ((double) (x - window.getSize().x / 2.0)) / + (window.getSize().x / 2.0) * 75); + } + break; + case 2: //left + y = yPos(gen); //get random yPos + if (y <= window.getSize().y / + 2) { //if on top half of window (calculate angle to point towards window) + angle = uniform_int_distribution( + 300, 345 + ((double) y) / (window.getSize().y / 2.0) * 75); + } else { //else + angle = uniform_int_distribution(-60 + ((double) (y - window.getSize().y / 2.0)) / + (window.getSize().y / 2.0) * 75, 60); + } + break; + case 3: //bottom + x = xPos(gen); //get random xPos + y = window.getSize().y; + if (x <= window.getSize().x / + 2) { //if on left half of window (calculate angle to point towards window) + angle = uniform_int_distribution( + 30, 150 - ((double) x) / (window.getSize().x / 2.0) * 75); + } else { //else + angle = uniform_int_distribution(105 - ((double) (x - window.getSize().x / 2.0)) / + (window.getSize().x / 2.0) * 75, 150); + } + break; + case 4: //right + y = yPos(gen); //get random yPos + x = window.getSize().x; + if (y <= window.getSize().y / + 2) { //if on top half of window (calculate angle to point towards window) + angle = uniform_int_distribution( + 195 - ((double) y) / (window.getSize().y / 2.0) * 75, 240); + } else { //else + angle = uniform_int_distribution(120, 165 + + ((double) (y - window.getSize().y / 2.0)) / + (window.getSize().y / 2.0) * 75); + } + break; + } + + int size = stroidSize(gen); + switch (size) { + case 1: + enemies.push_back( + new Asteroid(size, size * 100, *smallAsteroids[smallTexture(gen)], scale(gen), x, y, + velocity(gen), (360 + angle(gen)) % 360)); + break; + case 2: + enemies.push_back( + new Asteroid(size, size * 100, *mediumAsteroids[mediumTexture(gen)], scale(gen), x, + y, velocity(gen), (360 + angle(gen)) % 360)); + break; + case 3: + enemies.push_back( + new Asteroid(size, size * 100, *largeAsteroids[largeTexture(gen)], scaleLarge(gen), + x, y, velocity(gen), (360 + angle(gen)) % 360)); + break; + } + } + spawnClock.restart(); + } + + //**************************************** + // Spawn cycle above here + //**************************************** + + //**************************************** + // Object updates/deletion + //**************************************** + + player.update(&window); + + for (int i = 0; i < projectiles.size(); i++) { + projectiles[i]->update(&window); + + if (projectiles[i]->toBeErased()) { + projectiles.erase(projectiles.begin() + i); + } + } + + for (int i = 0; i < enemies.size(); i++) { + enemies[i]->update(&window); + + if (enemies[i]->toBeErased()) { + enemies.erase(enemies.begin() + i); + } + } + + for (int i = 0; i < enemies.size(); i++) { + for (int j = 0; j < projectiles.size(); j++) { + if (Collision::PixelPerfectTest(*enemies[i], *projectiles[j], 0)) { + uniform_int_distribution angle(0, 359); + enemies[i]->setHealth(enemies[i]->getHealth() - 1); + if (enemies[i]->getHealth() <= 0) { + if (enemies[i]->getType() == "asteroid") + ((Asteroid *) enemies[i])->hit(animations, enemyBoom, explosion, gen); + player.setScore(player.getScore() + enemies[i]->getPoints()); + enemies.erase(enemies.begin() + i); + } else { + animations.push_back( + new MySprite(explosion, 20, projectiles[j]->getXPos(), projectiles[j]->getYPos(), 0, + angle(gen))); + animations[animations.size() - 1]->makeAnimated(5, 5, 0.01, 23); + } + + projectiles.erase(projectiles.begin() + j); + } + } + } + + for (int i = 0; i < enemies.size(); i++) { + if (player.hasShield() && Collision::CircleTest(*enemies[i], *player.getRider().sprite)) { + if (enemies[i]->getType() == "asteroid") + ((Asteroid *) enemies[i])->hit(animations, enemyBoom, explosion, gen); + enemies.erase(enemies.begin() + i); + } else if (Collision::CircleTest(*enemies[i], player)) { + if (!ended && player.hit(window, animations, explosion, gen, shield, 12, shieldTimer)) { + ended = true; + } + gui.erase(gui.begin() + player.getLives() + 1); //remove player icon from top corner + } + } + + for (int i = 0; i < animations.size(); i++) { + animations[i]->update(&window); + if (animations[i]->getAnimation().isPlayed) + animations.erase(animations.begin() + i); + } + + score.setString("Score: " + to_string(player.getScore())); + + if (player.getScore() - (player.getNewLifeScore() * player.getNumLivesAdded()) >= + player.getNewLifeScore()) { + player.newLife(gui, ship, window, newLife); + } + + //**************************************** + // Object updates, deletions, collisions above + //**************************************** + + //**************************************** + // ADD ALL OF OUR DRAWING BELOW HERE + //**************************************** + + window.draw(*gui[0]); //draw background + + for (int i = 0; i < projectiles.size(); i++) + window.draw(*projectiles[i]); + for (int i = 0; i < enemies.size(); i++) + window.draw(*enemies[i]); + + for (MySprite *a : animations) + window.draw(*a); + + if (!ended) { + window.draw(player); + + if (player.getRider().sprite != nullptr) + window.draw(*player.getRider().sprite); + } else { + for (auto d : lost) window.draw(*d); + } + + for (int i = 1; i < gui.size(); i++) { + window.draw(*gui[i]); + } + //**************************************** + // ADD ALL OF OUR DRAWING ABOVE HERE + //**************************************** + + window.display(); // display the window + + //**************************************** + // HANDLE EVENTS BELOW HERE + //**************************************** + Event event; + while (window.pollEvent(event)) { // ask the window if any events occurred + if (event.type == Event::Closed) { // if event type is a closed event + // i.e. they clicked the X on the window + window.close(); // then close our window + } + } + } + + return 1; // report our program exited successfully + } +}; \ No newline at end of file diff --git a/Menu.h b/Menu.h new file mode 100644 index 0000000..786cceb --- /dev/null +++ b/Menu.h @@ -0,0 +1,472 @@ +// +// Created by benmo on 2/20/2020. +// + +#ifndef SFML_TEMPLATE_MENU_H +#define SFML_TEMPLATE_MENU_H + +#include +#include +#include + +class Menu { +public: + int result; + bool soundOn = true, musicOn = true; + + Menu() { + result = init(); + } +private: + sf::SoundBuffer bip; + sf::Sound bipSound; + bool playedBip = false; + + int init() { + const int MENU = 0, CREDITS = 1; + int screen = 0; + + std::vector buttons; + std::vector text; + + std::vector credits; + std::vector creditsGUI; + + sf::RenderWindow window( sf::VideoMode(1240, 640), "Asteroids" ); + sf::View mainView; + mainView.setCenter(window.getSize().x/(float)2.0, window.getSize().y/(float)2.0); + mainView.setSize(window.getSize().x, window.getSize().y); + window.setView(mainView); + window.setPosition(sf::Vector2i(window.getPosition().x, window.getPosition().y - 50)); + + /************************************************* + * File Input && Processing + *************************************************/ + sf::Font sk; + sk.loadFromFile("data/Fonts/Sk.ttf"); + + sf::Font skME; + skME.loadFromFile("data/Fonts/SKoME.ttf"); + + sf::Font xolo; + xolo.loadFromFile("data/Fonts/Xolonium-Bold.ttf"); + + sf::Font monkirta; + monkirta.loadFromFile("data/Fonts/Monkirta Pursuit NC.ttf"); + + sf::Font oxan; + oxan.loadFromFile("data/Fonts/Oxanium-Light.ttf"); + + sf::Texture back; + back.loadFromFile("data/Gui/space.png"); + back.setRepeated(true); + + sf::Texture button; + button.loadFromFile("data/Gui/button.png"); + + sf::Texture box; + box.loadFromFile("data/Gui/window.png"); + + sf::Texture boxSm; + boxSm.loadFromFile("data/Gui/windowSm.png"); + + sf::Texture cloud; + cloud.loadFromFile("data/Gui/cloud.png"); + + sf::Texture leftArrow; + leftArrow.loadFromFile("data/Gui/Backward_BTN.png"); + + sf::Texture soundBTN; + soundBTN.loadFromFile("data/Gui/Sound.png"); + + sf::Texture musicBTN; + musicBTN.loadFromFile("data/Gui/Music.png"); + + sf::Texture initials; + initials.loadFromFile("data/Morgan Ben initials.png"); + + sf::Music menuLoop; + menuLoop.openFromFile("data/Sounds/Unknown Theme.wav"); + menuLoop.setLoop(true); + menuLoop.play(); + + bip.loadFromFile("data/Sounds/rollover.wav"); + + /************************************************* + * Object Initialization + *************************************************/ + + //Background pan sprite + sf::Sprite background(back); + sf::FloatRect fBounds(mainView.getCenter().x, mainView.getCenter().y, background.getTexture()->getSize().x * 3, background.getTexture()->getSize().y * 3); + sf::IntRect iBounds(fBounds); + + background.setTextureRect(iBounds); + background.setPosition(mainView.getCenter()); + background.setOrigin(iBounds.width/(float)2.0,iBounds.height/(float)2.0); + + //Sound settings + MySprite soundButton(soundBTN, 25, 35, 37, 0, 0); + MySprite musicButton(musicBTN, 25, soundButton.getXPos() + soundButton.getGlobalBounds().width, soundButton.getYPos(), 0, 0); + + //Title text + sf::Text title("Asteroids", skME, 90); + title.setPosition(mainView.getCenter().x, mainView.getCenter().y - window.getSize().y / (float)3.0); + title.setFillColor(sf::Color::White); + title.setLetterSpacing(title.getLetterSpacing() + (float)0.5); + title.setOrigin(title.getGlobalBounds().width/(float)2.0, title.getGlobalBounds().height/(float)2.0); + + MySprite inits(initials, 15); + inits.setPosition(window.getSize().x - inits.getGlobalBounds().width + 10, window.getSize().y - inits.getGlobalBounds().height); + + //Start button & text + MySprite startButton(button, 55); + startButton.setPosition(mainView.getCenter().x, mainView.getCenter().y - window.getSize().y / (float)12.0); + + //default button color + sf::Color defButtonColor = startButton.getColor(); + + sf::Text startText("Start", sk, 28); + startText.setPosition(startButton.getPosition().x, startButton.getPosition().y - 7); + startText.setFillColor(sf::Color(0,0,0,0)); + startText.setOutlineColor(sf::Color::White); + startText.setOutlineThickness(1); + startText.setLetterSpacing(startText.getLetterSpacing() + 1); + startText.setOrigin(startText.getLocalBounds().width/2, startText.getLocalBounds().height/2); + + //Credits button & text + MySprite creditsButton(button, 55); + creditsButton.setPosition(mainView.getCenter().x, mainView.getCenter().y); + + sf::Text creditsText("Credits", sk, 28); + creditsText.setPosition(creditsButton.getPosition().x, creditsButton.getPosition().y - 6); + creditsText.setFillColor(sf::Color(0,0,0,0)); + creditsText.setOutlineColor(sf::Color::White); + creditsText.setOutlineThickness(1); + creditsText.setLetterSpacing(creditsText.getLetterSpacing() + 1); + creditsText.setOrigin(creditsText.getLocalBounds().width/2, creditsText.getLocalBounds().height/2); + + //Exit button & text + MySprite exitButton(button, 55); + exitButton.setPosition(mainView.getCenter().x, mainView.getCenter().y + window.getSize().y / (float)12.0); + + sf::Text exitText("Exit", sk, 28); + exitText.setPosition(mainView.getCenter().x, exitButton.getPosition().y - 6); + exitText.setFillColor(sf::Color(0,0,0,0)); + exitText.setOutlineColor(sf::Color::White); + exitText.setOutlineThickness(1); + exitText.setLetterSpacing(exitText.getLetterSpacing() + 1); + exitText.setOrigin(exitText.getLocalBounds().width/2, exitText.getLocalBounds().height/2); + + buttons.push_back(&startButton); + buttons.push_back(&creditsButton); + buttons.push_back(&exitButton); + + text.push_back(&startText); + text.push_back(&creditsText); + text.push_back(&exitText); + + //Credits + sf::Text creditsTitle("Credits + Resources", sk, 70); + creditsTitle.setPosition(mainView.getCenter().x, window.getSize().y / (float)14.0); + creditsTitle.setFillColor(sf::Color::White); + creditsTitle.setOrigin(creditsTitle.getGlobalBounds().width/2, creditsTitle.getGlobalBounds().height/2); + + //Credits box + sf::Text credsTitle("Credits", xolo, 28); + credsTitle.setOrigin(credsTitle.getGlobalBounds().width/2, credsTitle.getGlobalBounds().height/2); + credsTitle.setPosition(mainView.getSize().x/(float)5.1, mainView.getSize().y/2 + mainView.getSize().y/22); + credsTitle.setFillColor(sf::Color::White); + + sf::Text music("River Schreckengost - ", monkirta, 20); + music.setOrigin(music.getGlobalBounds().width/2, music.getGlobalBounds().height/2); + music.setPosition(mainView.getSize().x/(float)5.8, mainView.getSize().y/(float)2 + mainView.getSize().y/(float)8.5); + music.setFillColor(sf::Color::White); + + sf::Text musicText("Music", oxan, 15); + musicText.setPosition(mainView.getSize().x/(float)5.8 + music.getGlobalBounds().width/2, mainView.getSize().y/(float)2 + mainView.getSize().y/(float)8.925); + musicText.setFillColor(sf::Color::White); + + sf::Text musicLabel("Instagram - ", monkirta, 15); + musicLabel.setPosition(mainView.getSize().x/(float)11.5, mainView.getSize().y/(float)2 + mainView.getSize().y/(float)7.3); + musicLabel.setFillColor(sf::Color::White); + + sf::Text musicText0("@river.schreck", oxan, 12); + musicText0.setPosition(mainView.getSize().x/(float)11.5 + musicLabel.getGlobalBounds().width, mainView.getSize().y/(float)2 + mainView.getSize().y/(float)7.15); + musicText0.setFillColor(sf::Color::White); + musicText0.setStyle(sf::Text::Style::Underlined); + + sf::Text musicLabel0("SoundCloud - ", monkirta, 15); + musicLabel0.setPosition(mainView.getSize().x/(float)11.5, mainView.getSize().y/(float)2 + mainView.getSize().y/(float)6.1); + musicLabel0.setFillColor(sf::Color::White); + + sf::Text musicText1("River Ethans", oxan, 12); + musicText1.setPosition(mainView.getSize().x/(float)11.5 + musicLabel0.getGlobalBounds().width, mainView.getSize().y/(float)2 + mainView.getSize().y/(float)5.95); + musicText1.setFillColor(sf::Color::White); + musicText1.setStyle(sf::Text::Style::Underlined); + + //Resources Box + sf::Text resourcesTitle("Resources", xolo, 28); + resourcesTitle.setOrigin(resourcesTitle.getGlobalBounds().width/2, resourcesTitle.getGlobalBounds().height/2); + resourcesTitle.setPosition(mainView.getSize().x - mainView.getSize().x/(float)4.95, mainView.getSize().y/(float)4.8); + resourcesTitle.setFillColor(sf::Color::White); + + //Dev box + sf::Text developerTitle("Developer: ", xolo, 25); + developerTitle.setPosition(mainView.getSize().x/13, mainView.getSize().y/(float)5.2); + developerTitle.setFillColor(sf::Color(0,0,0,0)); + developerTitle.setOutlineThickness(.8); + developerTitle.setOutlineColor(sf::Color::White); + + sf::Text developer("Benjamin Morgan", monkirta, 20); + developer.setOrigin(developer.getGlobalBounds().width/2, developer.getGlobalBounds().height/2); + developer.setPosition(mainView.getSize().x/(float)6.725, mainView.getSize().y/(float)3.95); + developer.setFillColor(sf::Color::White); + + sf::Text devLabel("Site - ", monkirta, 15); + devLabel.setPosition(mainView.getSize().x/(float)11.5, mainView.getSize().y/(float)3.65); + devLabel.setFillColor(sf::Color::White); + + sf::Text devText("https://www.benrmorgan.com/", oxan, 12); + devText.setPosition(mainView.getSize().x/(float)11.5 + devLabel.getGlobalBounds().width, mainView.getSize().y/(float)3.6); + devText.setFillColor(sf::Color::White); + devText.setStyle(sf::Text::Style::Underlined); + + sf::Text devLabel0("Github - ", monkirta, 15); + devLabel0.setPosition(mainView.getSize().x/(float)11.5, mainView.getSize().y/(float)3.35); + devLabel0.setFillColor(sf::Color::White); + + sf::Text devText0("bMorgan01", oxan, 12); + devText0.setPosition(mainView.getSize().x/(float)11.5 + devLabel0.getGlobalBounds().width, mainView.getSize().y/(float)3.3); + devText0.setFillColor(sf::Color::White); + devText0.setStyle(sf::Text::Style::Underlined); + + sf::Text devLabel1("Email - ", monkirta, 15); + devLabel1.setPosition(mainView.getSize().x/(float)11.5, mainView.getSize().y/(float)3.1); + devLabel1.setFillColor(sf::Color::White); + + sf::Text devText1("ben@benrmorgan.com", oxan, 12); + devText1.setPosition(mainView.getSize().x/(float)11.5 + devLabel1.getGlobalBounds().width, mainView.getSize().y/(float)3.05); + devText1.setFillColor(sf::Color::White); + + sf::Text devLabel2("Repo - ", monkirta, 15); + devLabel2.setPosition(mainView.getSize().x/(float)11.5, mainView.getSize().y/(float)2.87); + devLabel2.setFillColor(sf::Color::White); + + sf::Text devText2("https://github.com/bMorgan01/StarCap", oxan, 12); + devText2.setPosition(mainView.getSize().x/(float)11.5 + devLabel2.getGlobalBounds().width, mainView.getSize().y/(float)2.83); + devText2.setFillColor(sf::Color::White); + devText2.setStyle(sf::Text::Style::Underlined); + + //Credits GUI + sf::Sprite backButton(leftArrow); + backButton.setScale(.3, .3); + backButton.setPosition(33, 100); + + sf::Sprite textBox(box); + textBox.setScale(.35, .35); + textBox.setPosition(mainView.getSize().x - mainView.getSize().x/3, mainView.getSize().y/(float)5.5); + + sf::Sprite textBoxSm(boxSm); + textBoxSm.setScale(.35, .35); + textBoxSm.setPosition(mainView.getSize().x/15, mainView.getSize().y/2 + mainView.getSize().y/50); + + sf::Sprite devBox(cloud); + devBox.setScale(.442, .442); + devBox.setPosition(mainView.getSize().x/15 - 2, mainView.getSize().y/(float)5.5); + + sf::Sprite issueButton(button); + issueButton.setColor(sf::Color::Red); + issueButton.setScale(40.0/100.0, 40.0/100.0); + issueButton.setOrigin(issueButton.getGlobalBounds().width/2, issueButton.getGlobalBounds().height/2); + issueButton.setPosition(mainView.getSize().x/(float)6.2, mainView.getSize().y/(float)2.52); + + sf::Text issueText("Report Bug", sk, 16); + issueText.setPosition(issueButton.getPosition().x - 21, issueButton.getPosition().y); + issueText.setFillColor(sf::Color(0,0,0,0)); + issueText.setFillColor(sf::Color::White); + + credits.push_back(&creditsTitle); + credits.push_back(&developerTitle); + credits.push_back(&credsTitle); + credits.push_back(&music); + credits.push_back(&musicText); + credits.push_back(&musicLabel); + credits.push_back(&musicText0); + credits.push_back(&musicLabel0); + credits.push_back(&musicText1); + credits.push_back(&resourcesTitle); + credits.push_back(&developer); + credits.push_back(&devLabel); + credits.push_back(&devText); + credits.push_back(&devLabel0); + credits.push_back(&devText0); + credits.push_back(&devLabel1); + credits.push_back(&devText1); + credits.push_back(&devLabel2); + credits.push_back(&devText2); + credits.push_back(&issueText); + + creditsGUI.push_back(&backButton); + creditsGUI.push_back(&textBox); + creditsGUI.push_back(&textBoxSm); + creditsGUI.push_back(&devBox); + creditsGUI.push_back(&issueButton); + + while( window.isOpen() ) { + /********************************************* + * Pre-draw ops here. + *********************************************/ + + + /********************************************* + * Drawing goes here. + *********************************************/ + + window.clear( sf::Color::Black ); // clear the contents of the old frame + + window.draw(background); + + switch(screen) { + case MENU: + /************** + * Draw Menu + **************/ + backButton.setPosition(33, 100); + + //Sound buttons + window.draw(soundButton); + window.draw(musicButton); + + //Title text + window.draw(title); + + for (int i = 0; i < buttons.size(); i++) { + window.draw(*buttons[i]); + window.draw(*text[i]); + } + + window.draw(inits); + break; + case CREDITS: + /************** + * Draw Credits + **************/ + backButton.setPosition(33, 27); + + for (sf::Sprite *s : creditsGUI) { + window.draw(*s); + } + + for (sf::Text *t : credits) { + window.draw(*t); + } + + break; + } + + window.display(); // display the window + + sf::Event event{}; + while( window.pollEvent(event) ) { // ask the window if any events occurred + + /********************************************* + * Event handling here. + *********************************************/ + sf::Vector2i mousePos = sf::Mouse::getPosition( window ); + sf::Vector2f mousePosF( static_cast( mousePos.x ), static_cast( mousePos.y ) ); + + switch (event.type) { + case sf::Event::Closed: //user clicked X button + window.close(); + break; + case sf::Event::MouseButtonPressed: //User clicked mouse + if (exitButton.getGlobalBounds().contains(mousePosF) && screen == MENU) { + playBip(); + return EXIT_FAILURE; + } else if (startButton.getGlobalBounds().contains(mousePosF) && screen == MENU) { + playBip(); + return EXIT_SUCCESS; + } else if (creditsButton.getGlobalBounds().contains(mousePosF) && screen == MENU) { + playBip(); + screen = CREDITS; + } else if (issueButton.getGlobalBounds().contains(mousePosF) && screen == CREDITS) { + playBip(); + ShellExecute(nullptr, "open", "https://github.com/bMorgan01/StarCap/issues", nullptr, nullptr, SW_SHOWNORMAL); + } else if (devText.getGlobalBounds().contains(mousePosF) && screen == CREDITS) { + playBip(); + ShellExecute(nullptr, "open", "https://www.benrmorgan.com", nullptr, nullptr, SW_SHOWNORMAL); + } else if (devText0.getGlobalBounds().contains(mousePosF) && screen == CREDITS) { + playBip(); + ShellExecute(nullptr, "open", "https://github.com/bMorgan01", nullptr, nullptr, SW_SHOWNORMAL); + } else if (devText2.getGlobalBounds().contains(mousePosF) && screen == CREDITS) { + playBip(); + ShellExecute(nullptr, "open", "https://github.com/bMorgan01/StarCap", nullptr, nullptr, SW_SHOWNORMAL); + } else if (musicText0.getGlobalBounds().contains(mousePosF) && screen == CREDITS) { + playBip(); + ShellExecute(nullptr, "open", "https://www.instagram.com/river.schreck/", nullptr, nullptr, SW_SHOWNORMAL); + } else if (musicText1.getGlobalBounds().contains(mousePosF) && screen == CREDITS) { + playBip(); + ShellExecute(nullptr, "open", "https://soundcloud.com/riverethans", nullptr, nullptr, SW_SHOWNORMAL); + } else if (backButton.getGlobalBounds().contains(mousePosF) && screen == CREDITS) { + playBip(); + screen = MENU; + } else if (soundButton.getGlobalBounds().contains(mousePosF) && screen == MENU) { + soundOn = !soundOn; + playBip(); + } else if (musicButton.getGlobalBounds().contains(mousePosF) && screen == MENU) { + playBip(); + musicOn = !musicOn; + if (!musicOn) menuLoop.setVolume(0); + else menuLoop.setVolume(100); + } + break; + case sf::Event::MouseMoved: + if (exitButton.getGlobalBounds().contains(mousePosF) && screen == MENU) exitButton.setColor(sf::Color::Red); + else if (startButton.getGlobalBounds().contains(mousePosF) && screen == MENU) startButton.setColor(sf::Color::Red); + else if (creditsButton.getGlobalBounds().contains(mousePosF) && screen == MENU) creditsButton.setColor(sf::Color::Red); + else if (issueButton.getGlobalBounds().contains(mousePosF) && screen == CREDITS) issueButton.setColor(sf::Color::Green); + else if (devText.getGlobalBounds().contains(mousePosF) && screen == CREDITS) devText.setFillColor(sf::Color::Red); + else if (devText0.getGlobalBounds().contains(mousePosF) && screen == CREDITS) devText0.setFillColor(sf::Color::Red); + else if (devText2.getGlobalBounds().contains(mousePosF) && screen == CREDITS) devText2.setFillColor(sf::Color::Red); + else if (musicText0.getGlobalBounds().contains(mousePosF) && screen == CREDITS) musicText0.setFillColor(sf::Color::Red); + else if (musicText1.getGlobalBounds().contains(mousePosF) && screen == CREDITS) musicText1.setFillColor(sf::Color::Red); + else if (backButton.getGlobalBounds().contains(mousePosF) && screen == CREDITS) backButton.setColor(sf::Color::Red); + else if (soundButton.getGlobalBounds().contains(mousePosF) && soundOn && screen == MENU) soundButton.setColor(sf::Color::Red); + else if (musicButton.getGlobalBounds().contains(mousePosF) && musicOn && screen == MENU) musicButton.setColor(sf::Color::Red); + else if (soundButton.getGlobalBounds().contains(mousePosF) && !soundOn && screen == MENU) soundButton.setColor(sf::Color::White); + else if (musicButton.getGlobalBounds().contains(mousePosF) && !musicOn && screen == MENU) musicButton.setColor(sf::Color::White); + break; + } + + if (!exitButton.getGlobalBounds().contains(mousePosF)) exitButton.setColor(defButtonColor); + if (!startButton.getGlobalBounds().contains(mousePosF)) startButton.setColor(defButtonColor); + if (!creditsButton.getGlobalBounds().contains(mousePosF)) creditsButton.setColor(defButtonColor); + if (!issueButton.getGlobalBounds().contains(mousePosF)) issueButton.setColor(sf::Color::Red); + if (!devText.getGlobalBounds().contains(mousePosF)) devText.setFillColor(sf::Color::White); + if (!devText0.getGlobalBounds().contains(mousePosF)) devText0.setFillColor(sf::Color::White); + if (!devText2.getGlobalBounds().contains(mousePosF)) devText2.setFillColor(sf::Color::White); + if (!musicText0.getGlobalBounds().contains(mousePosF)) musicText0.setFillColor(sf::Color::White); + if (!musicText1.getGlobalBounds().contains(mousePosF)) musicText1.setFillColor(sf::Color::White); + if (!backButton.getGlobalBounds().contains(mousePosF)) backButton.setColor(defButtonColor); + if (!soundButton.getGlobalBounds().contains(mousePosF) && soundOn) soundButton.setColor(sf::Color::White); + if (!musicButton.getGlobalBounds().contains(mousePosF) && musicOn) musicButton.setColor(sf::Color::White); + if (!soundButton.getGlobalBounds().contains(mousePosF) && !soundOn) soundButton.setColor(sf::Color::Red); + if (!musicButton.getGlobalBounds().contains(mousePosF) && !musicOn) musicButton.setColor(sf::Color::Red); + } + } + + return EXIT_FAILURE; + } + + void playBip() { + if (soundOn) { + bipSound.setBuffer(bip); + bipSound.setVolume(100); + bipSound.play(); + } + } +}; + + +#endif //SFML_TEMPLATE_MENU_H diff --git a/MySprite.h b/MySprite.h new file mode 100644 index 0000000..5f2b671 --- /dev/null +++ b/MySprite.h @@ -0,0 +1,328 @@ +// +// Created by benmo on 2/14/2020. +// + +#ifndef SFML_TEMPLATE_SPRITE_H +#define SFML_TEMPLATE_SPRITE_H + +#include +#include +#include + +using namespace sf; + +class MySprite: public sf::Sprite{ +protected: + struct Physics { + float velocity, direction, acceleration, maxVelocity, minVelocity; + float rotVelocity, rotAcceleration, maxRotVelocity; + float xPos, yPos; + }; + + struct Animation { + float frameLength; + unsigned int currframe = 0, columns, height, width, numFrames; + Clock clock; + bool isAnimated = false, isPlayed = false; + IntRect textureRect; + }; + + struct Rider { + MySprite* sprite; + bool followsDirection = false, followsPosition = true; + }; + + Physics spritePhysics{}; + + Animation spriteAnimation{}; + + Rider spriteRider{}; + + bool toErase = false, circularHitbox = false; +public: + enum EdgeBehavior { + IGNORE, LOOP, BOUNCE + }; + + EdgeBehavior edgeBehavior = IGNORE; + + constexpr static const double PI = 3.1415926; + + static double distance(sf::Vector2f pos1, sf::Vector2f pos2) { + return sqrt(pow(pos2.x - pos1.x, 2) + pow(pos2.y - pos1.y, 2)); + } + + MySprite() : sf::Sprite() { + spritePhysics.velocity = 0; + spritePhysics.xPos = 0; + spritePhysics.yPos = 0; + spritePhysics.direction = 0; + + setOrigin(getGlobalBounds().width/2,getGlobalBounds().height/2); + } + + explicit MySprite(const sf::Texture &texture) : sf::Sprite(texture) { + spritePhysics.velocity = 0; + spritePhysics.xPos = 0; + spritePhysics.yPos = 0; + spritePhysics.direction = 0; + + setOrigin(getGlobalBounds().width/2,getGlobalBounds().height/2); + } + + MySprite(const sf::Texture &texture, float scale) : sf::Sprite(texture) { + spritePhysics.velocity = 0; + spritePhysics.xPos = 0; + spritePhysics.yPos = 0; + spritePhysics.direction = 0; + + setOrigin(getGlobalBounds().width/2,getGlobalBounds().height/2); + setScale(scale/100, scale/100); + } + + MySprite(const sf::Texture &texture, const sf::IntRect &rectangle) : sf::Sprite(texture, rectangle) { + spritePhysics.velocity = 0; + spritePhysics.xPos = 0; + spritePhysics.yPos = 0; + spritePhysics.direction = 0; + + setOrigin(rectangle.width/(float)2.0,rectangle.height/(float)2.0); + + } + + MySprite(const sf::Texture &texture, float scale, float xPos, float yPos, float velocity, float direction) : sf::Sprite(texture) { + spritePhysics.velocity = velocity; + spritePhysics.xPos = xPos; + spritePhysics.yPos = yPos; + spritePhysics.direction = direction; + + setScale(scale/100, scale/100); + setOrigin(getLocalBounds().width/2, getLocalBounds().height/2); + setPosition(spritePhysics.xPos,spritePhysics.yPos); + setRotation(direction); + } + + MySprite(const sf::Texture &texture, float scale, float xPos, float yPos, float velocity, float maxVelocity, float direction, float rotVelocity, float maxRotVelocity) : sf::Sprite(texture) { + spritePhysics.velocity = velocity; + spritePhysics.xPos = xPos; + spritePhysics.yPos = yPos; + spritePhysics.direction = direction; + spritePhysics.rotVelocity = rotVelocity; + spritePhysics.maxVelocity = maxVelocity; + spritePhysics.maxRotVelocity = maxRotVelocity; + + setScale(scale/100, scale/100); + setOrigin(getLocalBounds().width/2, getLocalBounds().height/2); + setPosition(spritePhysics.xPos,spritePhysics.yPos); + setRotation(direction); + } + + MySprite(const sf::Texture &texture, float scale, float xPos, float yPos, float velocity, float acceleration, float maxVelocity, float direction, float rotVelocity, float rotAcceleration, float maxRotVelocity) : sf::Sprite(texture) { + spritePhysics.velocity = velocity; + spritePhysics.xPos = xPos; + spritePhysics.yPos = yPos; + spritePhysics.direction = direction; + spritePhysics.rotVelocity = rotVelocity; + spritePhysics.maxVelocity = maxVelocity; + spritePhysics.maxRotVelocity = maxRotVelocity; + spritePhysics.acceleration = acceleration; + spritePhysics.rotAcceleration = rotAcceleration; + + setScale(scale/100, scale/100); + setOrigin(getLocalBounds().width/2, getLocalBounds().height/2); + setPosition(spritePhysics.xPos,spritePhysics.yPos); + setRotation(direction); + } + + MySprite(const sf::Texture &texture, float scale, float xPos, float yPos, float velocity, float maxVelocity, float direction) : sf::Sprite(texture) { + spritePhysics.velocity = velocity; + spritePhysics.xPos = xPos; + spritePhysics.yPos = yPos; + spritePhysics.direction = direction; + spritePhysics.maxVelocity = maxVelocity; + + setScale(scale/100, scale/100); + setOrigin(getLocalBounds().width/2, getLocalBounds().height/2); + setPosition(spritePhysics.xPos,spritePhysics.yPos); + setRotation(direction); + } + + void makeAnimated(int rows, int columns, float length, int frames = 0) { + spriteAnimation.height = getTexture()->getSize().y/rows; + spriteAnimation.width = getTexture()->getSize().x/columns; + spriteAnimation.frameLength = length; + spriteAnimation.columns = columns; + + if (frames == 0) spriteAnimation.numFrames = rows*columns; + else spriteAnimation.numFrames = frames; + + spriteAnimation.isAnimated = true; + + spriteAnimation.textureRect = IntRect(0, 0, spriteAnimation.width, spriteAnimation.height); + setTextureRect(spriteAnimation.textureRect); + + setOrigin(spriteAnimation.width/2.0, spriteAnimation.height/2.0); + } + + void update(RenderWindow* window = nullptr) { + spritePhysics.xPos += cos(spritePhysics.direction * (PI/180)) * spritePhysics.velocity; + spritePhysics.yPos += -(sin(spritePhysics.direction * (PI/180)) * spritePhysics.velocity); + + if (edgeBehavior == LOOP) { + if (spritePhysics.xPos <= -getGlobalBounds().width) + spritePhysics.xPos = window->getSize().x + getGlobalBounds().width; + else if (spritePhysics.xPos >= window->getSize().x + getGlobalBounds().width) + spritePhysics.xPos = -getGlobalBounds().width; + + if (spritePhysics.yPos <= -getGlobalBounds().height) + spritePhysics.yPos = window->getSize().y + getGlobalBounds().height; + else if (spritePhysics.yPos >= window->getSize().y + getGlobalBounds().height) + spritePhysics.yPos = -getGlobalBounds().height; + } else if (edgeBehavior == IGNORE) { + if (spritePhysics.xPos <= -getGlobalBounds().width || + spritePhysics.xPos >= window->getSize().x + getGlobalBounds().width || + spritePhysics.yPos <= -getGlobalBounds().height || + spritePhysics.yPos >= window->getSize().y + getGlobalBounds().height) + toErase = true; + } + + spritePhysics.direction -= spritePhysics.rotVelocity; + spritePhysics.direction = fmod(spritePhysics.direction, 360); + if (spritePhysics.direction < 0) + spritePhysics.direction += 360; + + if (spriteAnimation.isAnimated) { + if (spriteAnimation.clock.getElapsedTime().asSeconds() > spriteAnimation.frameLength) { + spriteAnimation.currframe++; + if (spriteAnimation.currframe % spriteAnimation.columns == 0) { + spriteAnimation.textureRect.left = 0; + spriteAnimation.textureRect.top += spriteAnimation.height; + } else + spriteAnimation.textureRect.left += spriteAnimation.height; + + setTextureRect(spriteAnimation.textureRect); + spriteAnimation.clock.restart(); + + if (spriteAnimation.currframe == spriteAnimation.numFrames) { + spriteAnimation.isPlayed = true; + spriteAnimation.currframe = 0; + + spriteAnimation.textureRect.left = 0; + spriteAnimation.textureRect.top = 0; + } + + spriteAnimation.clock.restart(); + } + } + + if (spriteRider.sprite != nullptr) { + if (spriteRider.followsPosition) spriteRider.sprite->setPosition(spritePhysics.xPos, spritePhysics.yPos); + + if (spriteRider.followsDirection) spriteRider.sprite->setDirection(spritePhysics.direction); + } + + setPosition(spritePhysics.xPos, spritePhysics.yPos); + setRotation(-spritePhysics.direction); + } + + void accelerate(float override = 0, bool ignoreMax = false) { + if (override != 0) spritePhysics.velocity += override; + else spritePhysics.velocity += spritePhysics.acceleration; + + if (!ignoreMax && spritePhysics.velocity > spritePhysics.maxVelocity) spritePhysics.velocity = spritePhysics.maxVelocity; + if (!ignoreMax && spritePhysics.velocity < spritePhysics.minVelocity) spritePhysics.velocity = spritePhysics.minVelocity; + } + + void rotAccel(float override = 0, bool ignoreMax = false) { + if (override != 0) spritePhysics.rotVelocity += override; + else spritePhysics.rotVelocity += spritePhysics.rotAcceleration; + + if (!ignoreMax && spritePhysics.rotVelocity > spritePhysics.maxRotVelocity) spritePhysics.rotVelocity = spritePhysics.maxRotVelocity; + else if (!ignoreMax && -spritePhysics.rotVelocity > spritePhysics.maxRotVelocity) spritePhysics.rotVelocity = -spritePhysics.maxRotVelocity; + } + + void turn(float degrees) { + spritePhysics.direction -= degrees; + + setRotation(-spritePhysics.direction); + } + + float getXPos() { + return spritePhysics.xPos; + } + + float getYPos() { + return spritePhysics.yPos; + } + + void setPosition(float xPos, float yPos) { + spritePhysics.xPos = xPos; + spritePhysics.yPos = yPos; + + sf::Sprite::setPosition(sf::Vector2f(xPos, yPos)); + } + + void setPosition(const sf::Vector2f &vec) { + spritePhysics.xPos = vec.x; + spritePhysics.yPos = vec.y; + + sf::Sprite::setPosition(vec); + } + + float getDirection() { + return spritePhysics.direction; + } + + void setDirection(float angle) { + spritePhysics.direction = angle; + + setRotation(-angle); + } + + void setVelocity(float velo) { + spritePhysics.velocity = velo; + } + + float getVelocity() { + return spritePhysics.velocity; + } + + float getRotVelocity() { + return spritePhysics.rotVelocity; + }; + + void setMaxVelocity(float velo) { + spritePhysics.maxVelocity = velo; + } + + void setMinVelocity(float velo) { + spritePhysics.minVelocity = velo; + } + + void setMaxRotVelocity(float velo) { + spritePhysics.maxRotVelocity = velo; + } + + void setEdgeBehavior(EdgeBehavior behavior) { + edgeBehavior = behavior; + } + + bool toBeErased() const { + return toErase; + } + + void setRider(MySprite* sprite) { + spriteRider.sprite = sprite; + } + + Rider getRider() { + return spriteRider; + } + + Animation getAnimation() { + return spriteAnimation; + } +}; + + +#endif //SFML_TEMPLATE_SPRITE_H diff --git a/Ship.h b/Ship.h new file mode 100644 index 0000000..4ab4bbf --- /dev/null +++ b/Ship.h @@ -0,0 +1,87 @@ +// +// Created by benmo on 9/25/2020. +// + +#ifndef SFML_TEMPLATE_SHIP_H +#define SFML_TEMPLATE_SHIP_H + + +class Ship : public MySprite { +public: + Ship(const sf::Texture &texture, float scale, float xPos, float yPos, float velocity, float direction) : MySprite(texture, scale, xPos, yPos, velocity, direction) {} + + static void shoot(std::vector* projectiles, Sound &sound, sf::Texture &texture, float scale, float xPos, float yPos, float velocity, float direction) { + projectiles->push_back(new MySprite(texture, scale, xPos, yPos, velocity, direction)); + sound.play(); + } + + bool hit(RenderWindow &window, vector &animations, Texture &explosionTexture, default_random_engine &gen, Texture &shieldTexture, int scale, Clock &timer) { + uniform_int_distribution angle(0, 359); + animations.push_back(new MySprite(explosionTexture, 100, getXPos(), getYPos(), 0, angle(gen))); + animations[animations.size() - 1]->makeAnimated(5, 5, 0.01,23); + + setPosition(window.getSize().x/2, window.getSize().y/2); + setDirection(0); + setVelocity(0); + lives--; + setShield(true, &shieldTexture, scale, &timer); + + return lives <= 0; + } + + void newLife(vector &gui, Texture &life, RenderWindow &window, Sound &sound) { + setNumLivesAdded(getNumLivesAdded() + 1); + setLives(getLives() + 1); + gui.insert(gui.begin() + getLives(),new MySprite(life, 20, window.getSize().x - ((getLives()-1)*40 + 25), 25, 0, 270)); + sound.play(); + } + + int getLives() const { + return lives; + } + + void setLives(int lives) { + this->lives = lives; + } + + void setShield(bool shield, Texture* texture = nullptr, int scale = 0, Clock* timer = nullptr) { + this->shield = shield; + + if (shield) { + setRider(new MySprite(*texture, scale)); + timer->restart(); + } else + setRider(nullptr); + } + + bool hasShield() const { + return shield; + } + + int getScore() const { + return score; + } + + void setScore(int score) { + this->score = score; + } + + int getNewLifeScore() const { + return newLifeScore; + } + + int getNumLivesAdded() const { + return newLives; + } + + void setNumLivesAdded(int numLives) { + newLives = numLives; + } +private: + int lives = 3, score = 0, newLifeScore = 10000, newLives = 0; + + bool shield; +}; + + +#endif //SFML_TEMPLATE_SHIP_H diff --git a/data/Asteroids/(1).png b/data/Asteroids/(1).png new file mode 100644 index 0000000..fbf8a34 Binary files /dev/null and b/data/Asteroids/(1).png differ diff --git a/data/Asteroids/(10).png b/data/Asteroids/(10).png new file mode 100644 index 0000000..7b54ccc Binary files /dev/null and b/data/Asteroids/(10).png differ diff --git a/data/Asteroids/(11).png b/data/Asteroids/(11).png new file mode 100644 index 0000000..a514385 Binary files /dev/null and b/data/Asteroids/(11).png differ diff --git a/data/Asteroids/(12).png b/data/Asteroids/(12).png new file mode 100644 index 0000000..29fc5f7 Binary files /dev/null and b/data/Asteroids/(12).png differ diff --git a/data/Asteroids/(13).png b/data/Asteroids/(13).png new file mode 100644 index 0000000..2a2313b Binary files /dev/null and b/data/Asteroids/(13).png differ diff --git a/data/Asteroids/(14).png b/data/Asteroids/(14).png new file mode 100644 index 0000000..3aa5a47 Binary files /dev/null and b/data/Asteroids/(14).png differ diff --git a/data/Asteroids/(15).png b/data/Asteroids/(15).png new file mode 100644 index 0000000..d626a54 Binary files /dev/null and b/data/Asteroids/(15).png differ diff --git a/data/Asteroids/(16).png b/data/Asteroids/(16).png new file mode 100644 index 0000000..c0c1206 Binary files /dev/null and b/data/Asteroids/(16).png differ diff --git a/data/Asteroids/(17).png b/data/Asteroids/(17).png new file mode 100644 index 0000000..ca0d0d9 Binary files /dev/null and b/data/Asteroids/(17).png differ diff --git a/data/Asteroids/(18).png b/data/Asteroids/(18).png new file mode 100644 index 0000000..f31f790 Binary files /dev/null and b/data/Asteroids/(18).png differ diff --git a/data/Asteroids/(19).png b/data/Asteroids/(19).png new file mode 100644 index 0000000..35fc0a3 Binary files /dev/null and b/data/Asteroids/(19).png differ diff --git a/data/Asteroids/(2).png b/data/Asteroids/(2).png new file mode 100644 index 0000000..f932b5c Binary files /dev/null and b/data/Asteroids/(2).png differ diff --git a/data/Asteroids/(20).png b/data/Asteroids/(20).png new file mode 100644 index 0000000..1549e7f Binary files /dev/null and b/data/Asteroids/(20).png differ diff --git a/data/Asteroids/(21).png b/data/Asteroids/(21).png new file mode 100644 index 0000000..e3e5d86 Binary files /dev/null and b/data/Asteroids/(21).png differ diff --git a/data/Asteroids/(22).png b/data/Asteroids/(22).png new file mode 100644 index 0000000..e54c159 Binary files /dev/null and b/data/Asteroids/(22).png differ diff --git a/data/Asteroids/(23).png b/data/Asteroids/(23).png new file mode 100644 index 0000000..d62e8aa Binary files /dev/null and b/data/Asteroids/(23).png differ diff --git a/data/Asteroids/(3).png b/data/Asteroids/(3).png new file mode 100644 index 0000000..7e78c84 Binary files /dev/null and b/data/Asteroids/(3).png differ diff --git a/data/Asteroids/(4).png b/data/Asteroids/(4).png new file mode 100644 index 0000000..ab938fa Binary files /dev/null and b/data/Asteroids/(4).png differ diff --git a/data/Asteroids/(5).png b/data/Asteroids/(5).png new file mode 100644 index 0000000..64a0f20 Binary files /dev/null and b/data/Asteroids/(5).png differ diff --git a/data/Asteroids/(6).png b/data/Asteroids/(6).png new file mode 100644 index 0000000..7c99808 Binary files /dev/null and b/data/Asteroids/(6).png differ diff --git a/data/Asteroids/(7).png b/data/Asteroids/(7).png new file mode 100644 index 0000000..f6d31df Binary files /dev/null and b/data/Asteroids/(7).png differ diff --git a/data/Asteroids/(8).png b/data/Asteroids/(8).png new file mode 100644 index 0000000..d885397 Binary files /dev/null and b/data/Asteroids/(8).png differ diff --git a/data/Asteroids/(9).png b/data/Asteroids/(9).png new file mode 100644 index 0000000..d756cf2 Binary files /dev/null and b/data/Asteroids/(9).png differ diff --git a/data/Fonts/Monkirta Pursuit NC.ttf b/data/Fonts/Monkirta Pursuit NC.ttf new file mode 100644 index 0000000..a200e26 Binary files /dev/null and b/data/Fonts/Monkirta Pursuit NC.ttf differ diff --git a/data/Fonts/Oxanium-Light.ttf b/data/Fonts/Oxanium-Light.ttf new file mode 100644 index 0000000..a3ae4a3 Binary files /dev/null and b/data/Fonts/Oxanium-Light.ttf differ diff --git a/data/Fonts/SKoME.TTF b/data/Fonts/SKoME.TTF new file mode 100644 index 0000000..8bbc9b7 Binary files /dev/null and b/data/Fonts/SKoME.TTF differ diff --git a/data/Fonts/Sk.ttf b/data/Fonts/Sk.ttf new file mode 100644 index 0000000..65bea28 Binary files /dev/null and b/data/Fonts/Sk.ttf differ diff --git a/data/Fonts/Xolonium-Bold.ttf b/data/Fonts/Xolonium-Bold.ttf new file mode 100644 index 0000000..13e376f Binary files /dev/null and b/data/Fonts/Xolonium-Bold.ttf differ diff --git a/data/Fonts/arial.ttf b/data/Fonts/arial.ttf new file mode 100644 index 0000000..ff0815c Binary files /dev/null and b/data/Fonts/arial.ttf differ diff --git a/data/Gui/Armor_Icon.png b/data/Gui/Armor_Icon.png new file mode 100644 index 0000000..7f0c8ec Binary files /dev/null and b/data/Gui/Armor_Icon.png differ diff --git a/data/Gui/Backward_BTN.png b/data/Gui/Backward_BTN.png new file mode 100644 index 0000000..3e66c2d Binary files /dev/null and b/data/Gui/Backward_BTN.png differ diff --git a/data/Gui/FuelBar.png b/data/Gui/FuelBar.png new file mode 100644 index 0000000..8bcdcea Binary files /dev/null and b/data/Gui/FuelBar.png differ diff --git a/data/Gui/HP_Icon.png b/data/Gui/HP_Icon.png new file mode 100644 index 0000000..980c186 Binary files /dev/null and b/data/Gui/HP_Icon.png differ diff --git a/data/Gui/LoadingBarEmpty.png b/data/Gui/LoadingBarEmpty.png new file mode 100644 index 0000000..28addf8 Binary files /dev/null and b/data/Gui/LoadingBarEmpty.png differ diff --git a/data/Gui/LoadingBarFull.png b/data/Gui/LoadingBarFull.png new file mode 100644 index 0000000..7f83748 Binary files /dev/null and b/data/Gui/LoadingBarFull.png differ diff --git a/data/Gui/Music.png b/data/Gui/Music.png new file mode 100644 index 0000000..6c21c59 Binary files /dev/null and b/data/Gui/Music.png differ diff --git a/data/Gui/Sound.png b/data/Gui/Sound.png new file mode 100644 index 0000000..a6d7bab Binary files /dev/null and b/data/Gui/Sound.png differ diff --git a/data/Gui/Speed_Icon.png b/data/Gui/Speed_Icon.png new file mode 100644 index 0000000..ee8ec2d Binary files /dev/null and b/data/Gui/Speed_Icon.png differ diff --git a/data/Gui/Stats_Bar.png b/data/Gui/Stats_Bar.png new file mode 100644 index 0000000..e3fb124 Binary files /dev/null and b/data/Gui/Stats_Bar.png differ diff --git a/data/Gui/arrow.png b/data/Gui/arrow.png new file mode 100644 index 0000000..ffade9a Binary files /dev/null and b/data/Gui/arrow.png differ diff --git a/data/Gui/ball.png b/data/Gui/ball.png new file mode 100644 index 0000000..3d707e5 Binary files /dev/null and b/data/Gui/ball.png differ diff --git a/data/Gui/button.png b/data/Gui/button.png new file mode 100644 index 0000000..bdbdf62 Binary files /dev/null and b/data/Gui/button.png differ diff --git a/data/Gui/cloud.png b/data/Gui/cloud.png new file mode 100644 index 0000000..292278e Binary files /dev/null and b/data/Gui/cloud.png differ diff --git a/data/Gui/filter.xcf b/data/Gui/filter.xcf new file mode 100644 index 0000000..ead01df Binary files /dev/null and b/data/Gui/filter.xcf differ diff --git a/data/Gui/mapBox.png b/data/Gui/mapBox.png new file mode 100644 index 0000000..431ec92 Binary files /dev/null and b/data/Gui/mapBox.png differ diff --git a/data/Gui/money_bar.png b/data/Gui/money_bar.png new file mode 100644 index 0000000..4b1fa3c Binary files /dev/null and b/data/Gui/money_bar.png differ diff --git a/data/Gui/planetDialog.png b/data/Gui/planetDialog.png new file mode 100644 index 0000000..33036d6 Binary files /dev/null and b/data/Gui/planetDialog.png differ diff --git a/data/Gui/planetDialog.xcf b/data/Gui/planetDialog.xcf new file mode 100644 index 0000000..45a42b7 Binary files /dev/null and b/data/Gui/planetDialog.xcf differ diff --git a/data/Gui/smallButton.png b/data/Gui/smallButton.png new file mode 100644 index 0000000..b907b91 Binary files /dev/null and b/data/Gui/smallButton.png differ diff --git a/data/Gui/space.png b/data/Gui/space.png new file mode 100644 index 0000000..878b39e Binary files /dev/null and b/data/Gui/space.png differ diff --git a/data/Gui/space.xcf b/data/Gui/space.xcf new file mode 100644 index 0000000..ac39d9a Binary files /dev/null and b/data/Gui/space.xcf differ diff --git a/data/Gui/unexplored.png b/data/Gui/unexplored.png new file mode 100644 index 0000000..7f14cae Binary files /dev/null and b/data/Gui/unexplored.png differ diff --git a/data/Gui/unexplored.xcf b/data/Gui/unexplored.xcf new file mode 100644 index 0000000..1697c0f Binary files /dev/null and b/data/Gui/unexplored.xcf differ diff --git a/data/Gui/window.png b/data/Gui/window.png new file mode 100644 index 0000000..db88e86 Binary files /dev/null and b/data/Gui/window.png differ diff --git a/data/Gui/windowSm.png b/data/Gui/windowSm.png new file mode 100644 index 0000000..c802c49 Binary files /dev/null and b/data/Gui/windowSm.png differ diff --git a/data/Morgan Ben initials.png b/data/Morgan Ben initials.png new file mode 100644 index 0000000..fb45c7e Binary files /dev/null and b/data/Morgan Ben initials.png differ diff --git a/data/Ship.png b/data/Ship.png new file mode 100644 index 0000000..d65cf60 Binary files /dev/null and b/data/Ship.png differ diff --git a/data/Sounds/Menu Loop.wav b/data/Sounds/Menu Loop.wav new file mode 100644 index 0000000..73e61a1 Binary files /dev/null and b/data/Sounds/Menu Loop.wav differ diff --git a/data/Sounds/Unknown Theme.wav b/data/Sounds/Unknown Theme.wav new file mode 100644 index 0000000..9418765 Binary files /dev/null and b/data/Sounds/Unknown Theme.wav differ diff --git a/data/Sounds/error.wav b/data/Sounds/error.wav new file mode 100644 index 0000000..c0233d2 Binary files /dev/null and b/data/Sounds/error.wav differ diff --git a/data/Sounds/explosions.wav b/data/Sounds/explosions.wav new file mode 100644 index 0000000..4b2778c Binary files /dev/null and b/data/Sounds/explosions.wav differ diff --git a/data/Sounds/pew.wav b/data/Sounds/pew.wav new file mode 100644 index 0000000..e592960 Binary files /dev/null and b/data/Sounds/pew.wav differ diff --git a/data/Sounds/pling.wav b/data/Sounds/pling.wav new file mode 100644 index 0000000..52854e2 Binary files /dev/null and b/data/Sounds/pling.wav differ diff --git a/data/Sounds/rollover.wav b/data/Sounds/rollover.wav new file mode 100644 index 0000000..5dee46c Binary files /dev/null and b/data/Sounds/rollover.wav differ diff --git a/data/back.png b/data/back.png new file mode 100644 index 0000000..878b39e Binary files /dev/null and b/data/back.png differ diff --git a/data/blue.png b/data/blue.png new file mode 100644 index 0000000..1df3222 Binary files /dev/null and b/data/blue.png differ diff --git a/data/bubble.png b/data/bubble.png new file mode 100644 index 0000000..b460fb1 Binary files /dev/null and b/data/bubble.png differ diff --git a/data/explodeSheet.png b/data/explodeSheet.png new file mode 100644 index 0000000..2fc72a6 Binary files /dev/null and b/data/explodeSheet.png differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..4507d5a --- /dev/null +++ b/main.cpp @@ -0,0 +1,29 @@ +#include // for standard input/output +#include +using namespace std; // using the standard namespace + +#include // include the SFML Graphics Library +#include +#include "Collision.h" +using namespace sf; // using the sf namespace + +#include "MySprite.h" +#include "Ship.h" +#include "Asteroid.h" +#include "Menu.h" +#include "Game.h" + +int main() { + bool play = true; + + while (play) { + Menu menu; + if (menu.result == EXIT_SUCCESS) { + Game game; + if (game.result == 1) play = false; + } + else play = false; + } + + return 0; +} \ No newline at end of file