diff --git a/firstSFML/Actor.h b/firstSFML/Actor.h index 0bf8fea..86a03c5 100644 --- a/firstSFML/Actor.h +++ b/firstSFML/Actor.h @@ -3,13 +3,13 @@ class Actor : public Block { protected: - t_direcrion dir; - float yJumpSpeed = gravity_speed; - sf::Vector2f respawnPos; - bool isPlayer = false; + t_direcrion dir; // enum of entity's direction + float yJumpSpeed = GRAVITY_SPEED; // falling speed + sf::Vector2f respawnPos; // coords of the respawn + bool isPlayer = false; // entity is bot or player public: - int xMap, yMap; - bool coinAmountIncrease = false; + int xMap, yMap; // coords of an area where entity located + bool coinAmountIncrease = false; // should we increase coin amount ? bool inJump = false; bool onLeftStair = false; bool onRightStair = false; @@ -17,19 +17,22 @@ class Actor : public Block { bool downArrowPressed = false; bool leftArrowPressed = false; bool rightArrowPressed = false; - Actor(sf::Vector2f size) : Block(size) { // - object.setFillColor(sf::Color::Blue); + // create shape + Actor(sf::Vector2f size) : Block(size) { dir = none; } - void moveOn(sf::Vector2f distance) { + // move entity on a distance + void moveOn(sf::Vector2f distance) { distance.x *= dir; object.move(distance); sprite.move(distance); } - void setRespawn(sf::Vector2i coord) { + // initialize respawnPos + void setRespawn(sf::Vector2i coord) { respawnPos = {coord.x * BLOCK_SIZE_X, coord.y * BLOCK_SIZE_Y - BLOCK_SIZE_Y }; } - void respawn() { + // move player to the respawnPos + void respawn() { inJump = false; onLeftStair = false; onRightStair = false; @@ -37,53 +40,57 @@ class Actor : public Block { downArrowPressed = false; setPos(respawnPos); } - void setDir(enum direction d) { + // initialize direction enum + void setDir(enum direction d) { dir = d; } - void initJumpSpeed() { - yJumpSpeed = gravity_speed; + // set falling speed value to max + void initJumpSpeed() { + yJumpSpeed = GRAVITY_SPEED; } - void jump() { + // jump or fall + void jump() { myLog(Logger::DEBUG) << "inJump - " << ((inJump) ? "true" : "false") << endl; if (inJump == true) { lockJump = true; - moveOn({ x_move_speed, yJumpSpeed }); - myLog(Logger::DEBUG) << "Jumping on { " << x_move_speed << " ; " << yJumpSpeed << " }" << endl; - yJumpSpeed += jump_change_step; - if (yJumpSpeed >= 10) - yJumpSpeed = 0; + moveOn({ X_MOVE_SPEED, yJumpSpeed }); // continue jump + myLog(Logger::DEBUG) << "Jumping on { " << X_MOVE_SPEED << " ; " << yJumpSpeed << " }" << endl; + yJumpSpeed += JUMP_CHANGE_STEP; // change Oy speed value + if (yJumpSpeed >= -GRAVITY_SPEED * 2) // limit falling speed + yJumpSpeed = -GRAVITY_SPEED * 2; } else { - if (!onLeftStair && !onRightStair) { - myLog(Logger::DEBUG) << "Falling down, Y " << -gravity_speed << std::endl; - moveOn({ 0, -gravity_speed }); + if (!onLeftStair && !onRightStair) { // unable to jump or fall being on the stair + myLog(Logger::DEBUG) << "Falling down, Y " << -GRAVITY_SPEED << std::endl; + moveOn({ 0, -GRAVITY_SPEED }); // fall down lockJump = true; } - if (collision == bColl) { + if (collision == bColl) { // if we are on the ground initJumpSpeed(); } } if (collision == bColl || collision == tColl || collision == rColl || collision == lColl) { - inJump = false; + inJump = false; // stop jumping if we have any contact with surface } } - // more acc values can be decreased - int checkCollision(Block &obj2) { + // check entitiy's collision with an object + // empty texture - 4 | coin - 3 | bot - 2 | shape - 1 | no collision - 0 + int checkCollision(Block &obj2) { t_texture objSkin = obj2.getTexture(); - if (objSkin == noTexture) + if (objSkin == noTexture) // do not collide with empty blocks return 4; float deltaX = this->getSenter().x - obj2.getSenter().x; float deltaY = this->getSenter().y - obj2.getSenter().y; float intersectX = abs(deltaX) - (this->getSize().x / 2 + obj2.getSize().x / 2); // < 0 float intersectY = abs(deltaY) - (this->getSize().y / 2 + obj2.getSize().y / 2); // < 0 - if (objSkin != stairLeft && objSkin != stairRight) { + if (objSkin != stairLeft && objSkin != stairRight) { if (intersectX < 0.0f && intersectY < 0.0f) { - if (objSkin == bot) + if (objSkin == bot) // colliding with a mummy return 2; if (objSkin == coin) { - if (isPlayer) { + if (isPlayer) { // player collides with a coin obj2.hideCoin(); coinAmountIncrease = true; return 3; @@ -91,7 +98,7 @@ class Actor : public Block { return 0; } myLog(Logger::DEBUG) << "Colliding | intersectX = " << intersectX << "| intersectY = " << intersectY << endl; - if (intersectY < intersectX) { + if (intersectY < intersectX) { // move in the direction of higher intersect if (deltaX < 0) { // right intersect collision = rColl; myLog(Logger::DEBUG) << "right intersect, move X on " << intersectX << endl; @@ -109,15 +116,13 @@ class Actor : public Block { else { if (deltaY < 0) { // bottom intersect collision = bColl; - if (objSkin == bot) - respawn(); lockJump = false; myLog(Logger::DEBUG) << "bottom intersect, move Y on " << intersectY << std::endl; // Now check if we are near/on the stair switch (objSkin) { case stairLeftUnder: { myLog(Logger::DEBUG) << "\n\nChecking stairLeftUnder\n\n" << endl; - if (obj2.getSenter().x - x_move_speed <= this->getCoord().x && obj2.getSenter().x >= this->getCoord().x) { // senter of stair block = left side + 1 of the player + if (obj2.getSenter().x - X_MOVE_SPEED <= this->getCoord().x && obj2.getSenter().x >= this->getCoord().x) { // senter of stair block = left side + 1 of the player myLog(Logger::DEBUG) << "\n\nSenter\n\n" << endl; if (onLeftStair) { if (this->dir == toright) { @@ -129,7 +134,7 @@ class Actor : public Block { else { // not on stair if (this->dir == toleft && this->upArrowPressed) { onLeftStair = true; - setPos({ obj2.getSenter().x - x_move_speed, this->getCoord().y }); // for more accurate process + setPos({ obj2.getSenter().x - X_MOVE_SPEED, this->getCoord().y }); // for more accurate process myLog(Logger::DEBUG) << "\n\nPlayer is now onLeftStair = T R U E\n\n" << endl; break; } @@ -142,7 +147,7 @@ class Actor : public Block { } case stairLeftTop: { myLog(Logger::DEBUG) << "\n\nChecking stairLeftTop\n\n" << endl; - if (obj2.getSenter().x - x_move_speed <= this->getCoord().x && obj2.getSenter().x >= this->getCoord().x) { // senter of stair block = left side of the player + if (obj2.getSenter().x - X_MOVE_SPEED <= this->getCoord().x && obj2.getSenter().x >= this->getCoord().x) { // senter of stair block = left side of the player myLog(Logger::DEBUG) << "\n\nSenter\n\n" << endl; if (onLeftStair) { if (this->dir == toleft) { @@ -153,7 +158,7 @@ class Actor : public Block { else { // not on stair if (this->dir == toright && this->downArrowPressed) { onLeftStair = true; - setPos({ obj2.getSenter().x - x_move_speed, this->getCoord().y }); // for more accurate process + setPos({ obj2.getSenter().x - X_MOVE_SPEED, this->getCoord().y }); // for more accurate process myLog(Logger::DEBUG) << "\n\nPlayer is now onLeftStair = T R U E\n\n" << endl; break; } @@ -166,7 +171,7 @@ class Actor : public Block { } case stairRightUnder: { myLog(Logger::DEBUG) << "\n\nChecking stairRightUnder\n\n" << endl; - if (obj2.getSenter().x <= this->getCoord().x + this->getSize().x && obj2.getSenter().x + x_move_speed >= this->getCoord().x + this->getSize().x) { // senter of stair block = right side of the player + if (obj2.getSenter().x <= this->getCoord().x + this->getSize().x && obj2.getSenter().x + X_MOVE_SPEED >= this->getCoord().x + this->getSize().x) { // senter of stair block = right side of the player myLog(Logger::DEBUG) << "\n\nSenter\n\n" << endl; if (onRightStair) { if (this->dir == toleft) { @@ -177,7 +182,7 @@ class Actor : public Block { else { // not on stair if (this->dir == toright && this->upArrowPressed) { onRightStair = true; - setPos({ obj2.getSenter().x - this->getSize().x + x_move_speed, this->getCoord().y }); // for more accurate process + setPos({ obj2.getSenter().x - this->getSize().x + X_MOVE_SPEED, this->getCoord().y }); // for more accurate process myLog(Logger::DEBUG) << "\n\nPlayer is now onRightStair = T R U E\n\n" << endl; ///!!!!!!!!!!!!!!!!!!! break; } @@ -190,7 +195,7 @@ class Actor : public Block { } case stairRightTop: { myLog(Logger::DEBUG) << "\n\nChecking stairRightTop\n\n" << endl; - if (obj2.getSenter().x <= this->getCoord().x + this->getSize().x && obj2.getSenter().x + x_move_speed >= this->getCoord().x + this->getSize().x) { // senter of stair block = right side of the player + if (obj2.getSenter().x <= this->getCoord().x + this->getSize().x && obj2.getSenter().x + X_MOVE_SPEED >= this->getCoord().x + this->getSize().x) { // senter of stair block = right side of the player myLog(Logger::DEBUG) << "\n\nSenter\n\n" << endl; if (onRightStair) { if (this->dir == toright) { @@ -201,7 +206,7 @@ class Actor : public Block { else { // not on stair if (this->dir == toleft && this->downArrowPressed) { onRightStair = true; - setPos({ obj2.getSenter().x - this->getSize().x - x_move_speed, this->getCoord().y }); // for more accurate process + setPos({ obj2.getSenter().x - this->getSize().x - X_MOVE_SPEED, this->getCoord().y }); // for more accurate process myLog(Logger::DEBUG) << "\n\nPlayer is now onRightStair = T R U E\n\n" << endl; break; } @@ -224,7 +229,7 @@ class Actor : public Block { myLog(Logger::DEBUG) << "Checking default" << endl; if (!onLeftStair && !onRightStair) setPos({ this->getCoord().x , obj2.getSenter().y - (this->getSize().y + obj2.getSize().y / 2) }); - else if (intersectY > -x_move_speed) { // inters Y small + else if (intersectY > -X_MOVE_SPEED) { // inters Y small onLeftStair = false; onRightStair = false; } diff --git a/firstSFML/Block.h b/firstSFML/Block.h index f1744ea..7ec6b0c 100644 --- a/firstSFML/Block.h +++ b/firstSFML/Block.h @@ -8,7 +8,7 @@ using namespace std; class Block { protected: sf::RectangleShape object; - sf::Texture texture; + sf::Texture texture; // pointer to a picture sf::Sprite sprite; t_collided collision; t_texture skin = wall; @@ -16,33 +16,40 @@ class Block { public: bool lockJump = true; - Block() {} - Block(sf::Vector2f size) { // - object.setSize(size); // + // create instance of the class without initializing + Block() {} + // initialize shape + Block(sf::Vector2f size) { + object.setSize(size); object.setFillColor(sf::Color::Green); } - Block(sf::Vector2f size, string fname) { // - object.setSize(size); // + // initialize shape and set texture + Block(sf::Vector2f size, string fname) { + object.setSize(size); object.setFillColor(sf::Color::Green); // making sprite with the same parameters if (!texture.loadFromFile(fname)) { myLog(Logger::ERR) << "image load failed!" << endl; } - sprite.setTextureRect(sf::IntRect(0, 0, texture.getSize().x, texture.getSize().y)); + sprite.setTextureRect(sf::IntRect(0, 0, texture.getSize().x, texture.getSize().y)); // load full picture sprite.setTexture(texture); sprite.setScale({size.x / texture.getSize().x , size.y / texture.getSize().y }); } //noTexture = 0, wall = 1, stairLeftUnder = 2, stairLeft = 3, stairLeftTop = 4, stairRightUnder = 5, stairRight = 6, stairRightTop = 7, hardWall = 8 - void annulateCollision() { // at the beginning of the lap, no collision + // at the beginning of the lap, no collision + void annulateCollision() { collision = no; } - sf::Vector2f getSenter() { // return center of shape + // return the coords of the senter of shape + sf::Vector2f getSenter() { return { object.getPosition().x + object.getSize().x / 2 , object.getPosition().y + object.getSize().y / 2 }; } - sf::Vector2f getCoord() { - return object.getPosition(); + // return the coords of the top left corner of shape + sf::Vector2f getCoord() { + return object.getPosition(); } - void drawTo(sf::RenderWindow &window) { + // draw shape or texture to the window + void drawTo(sf::RenderWindow &window) { if (skin != noTexture) { if(xRay) window.draw(object); @@ -50,7 +57,8 @@ class Block { window.draw(sprite); } } - void setPos(sf::Vector2f newPosition) { + // move the top left corner of shape + void setPos(sf::Vector2f newPosition) { object.setPosition(newPosition); if(skin == stairLeft || skin == stairLeftTop) sprite.setPosition({ newPosition.x + PLAYER_SIZE_X / 3, newPosition.y }); // not proper begin moving on stairs @@ -59,13 +67,16 @@ class Block { else sprite.setPosition(newPosition); } - sf::Vector2f getSize() { + // get height and width + sf::Vector2f getSize() { return object.getSize(); } - t_texture getTexture() { + // get enum of the current texture + t_texture getTexture() { return skin; } - void create(t_texture nskin, int current_level) { // + // initialize texture enum, shape, coose and set texture + void create(t_texture nskin, int current_level) { skin = nskin; switch (skin) { case noTexture: { @@ -204,7 +215,8 @@ class Block { } } } - void hideCoin() { + // set empty texture to coin + void hideCoin() { if (!texture.loadFromFile("images/empty.png")) { myLog(Logger::ERR) << "image load failed!" << endl; } diff --git a/firstSFML/Constants.h b/firstSFML/Constants.h index 9ac3261..292e330 100644 --- a/firstSFML/Constants.h +++ b/firstSFML/Constants.h @@ -3,8 +3,9 @@ // screen settings constexpr float ASPECT_RATIO = 3.f / 4.f; -constexpr float WINDOW_SIZE_X = 1024.f; +constexpr float WINDOW_SIZE_X = 1024.f; // 1024.f constexpr float WINDOW_SIZE_Y = WINDOW_SIZE_X * ASPECT_RATIO; +constexpr int FPS_LOCK = 60; // map settings constexpr int MAX_MAP_SIZE_X = 64; @@ -12,34 +13,27 @@ constexpr int MAP_SIZE_X = 32; constexpr int MAP_SIZE_Y = 24; constexpr float BLOCK_SIZE_X = WINDOW_SIZE_X / MAP_SIZE_X; constexpr float BLOCK_SIZE_Y = WINDOW_SIZE_Y / MAP_SIZE_Y; + static bool xRay = false; -constexpr int LIVES_CONST = 4; -static int lives = LIVES_CONST; + // player settings constexpr float PLAYER_SIZE_X = WINDOW_SIZE_X / MAP_SIZE_X; constexpr float PLAYER_SIZE_Y = (WINDOW_SIZE_Y / MAP_SIZE_Y) * 2; +constexpr int LIVES_CONST = 4; +constexpr float CHANGE_TEXTURE_DELTA_X = 10.f; + +static int lives = LIVES_CONST; // gravity settings -static float gravity_speed = 0.f; -static float x_move_speed = 0.f; -static float jump_change_step = 0.f; -static float stair_move_speed = 0.f; -//Denys -constexpr float GRAVITY_SPEED_CONST = -5.0f; -constexpr float X_MOVE_SPEED_CONST = 2.0f; -constexpr float JUMP_CHANGE_STEP_CONST = 0.15f; -//Alex -constexpr float GRAVITY_SPEED_CONST1 = -4.7f; -constexpr float X_MOVE_SPEED_CONST1 = 4.0f; -constexpr float JUMP_CHANGE_STEP_CONST1 = 0.12f; +constexpr float X_MOVE_SPEED = WINDOW_SIZE_X / 512.f; // 2.0f +constexpr float GRAVITY_SPEED = X_MOVE_SPEED * -2.5f; // -5.0f +constexpr float JUMP_CHANGE_STEP = GRAVITY_SPEED * (-3.f / 100.f); // 0.15f + // enums typedef enum direction { toleft = -1, none = 0, toright = 1 } t_direcrion; -typedef enum condition { normal, inJump, onStairs } t_condition; -typedef enum collided { rColl, lColl, bColl, tColl, no, colliding } t_collided; -typedef enum heroMovement {} t_heroMovement; -typedef enum mummyMovement {} t_mummyMovement; -typedef enum texture { noTexture = 0, wall = 1, stairLeftUnder = 2, stairLeft = 3, stairLeftTop = 4, stairRightUnder = 5, stairRight = 6, stairRightTop = 7, hardWall = 8, bot = 9, coin = '*' } t_texture; typedef enum textureDir { leftTexture = 0, rightTexture = 1} t_textureDir; +typedef enum texture { noTexture = 0, wall = 1, stairLeftUnder = 2, stairLeft = 3, stairLeftTop = 4, stairRightUnder = 5, stairRight = 6, stairRightTop = 7, hardWall = 8, bot = 9, coin = '*' } t_texture; +typedef enum collided { rColl, lColl, bColl, tColl, no, colliding } t_collided; // logging static Logger myLog(Logger::ERR, Logger::WARN); diff --git a/firstSFML/Hero.h b/firstSFML/Hero.h index 01c62b1..83ac99c 100644 --- a/firstSFML/Hero.h +++ b/firstSFML/Hero.h @@ -1,16 +1,15 @@ #include "pch.h" class Hero : public Actor { - enum heroMovement move; string playerTexture[2][3] = { { "images/player_left_0.png", "images/player_left_1.png", "images/player_left_2.png" }, { "images/player_right_0.png", "images/player_right_1.png", "images/player_right_2.png" } }; - t_textureDir tDirection = leftTexture; - int textureCounter = 1; + t_textureDir tDirection = leftTexture; // enum to choose part of the first dimention of the texture array + int textureCounter = 1; // counter to choose texture in the second dimention of the texture array float lastPositionX; - const float deltaPositionX = 10.f; public: - Hero(sf::Vector2f size, string fname) : Actor(size) { // - object.setFillColor(sf::Color::Yellow); + // initialize sprite whith a texture + Hero(sf::Vector2f size, string fname) : Actor(size) { + object.setFillColor(sf::Color::Yellow); if (!texture.loadFromFile(fname)) { myLog(Logger::ERR) << "image load failed!" << endl; } @@ -19,7 +18,8 @@ class Hero : public Actor { sprite.setTexture(texture); sprite.setScale({ size.x / texture.getSize().x , size.y / texture.getSize().y }); } - void chooseTexture() { + // change textures while moving + void chooseTexture() { if (inJump == true) { this->texture.loadFromFile(playerTexture[tDirection][0]); } @@ -30,13 +30,14 @@ class Hero : public Actor { else { this->texture.loadFromFile(playerTexture[tDirection][textureCounter]); } - if (abs(lastPositionX - this->getCoord().x) >= deltaPositionX) { + if (abs(lastPositionX - this->getCoord().x) >= CHANGE_TEXTURE_DELTA_X) { lastPositionX = this->getCoord().x; textureCounter++; if (textureCounter >= 3) textureCounter = 0; } } + // auto move player void autoMoveOn(sf::Vector2f distance, t_direcrion autoDir) { distance.x *= autoDir; if (autoDir == toleft) { @@ -53,9 +54,9 @@ class Hero : public Actor { sprite.move(distance); chooseTexture(); } + // keypress detection void controle(sf::RenderWindow &window, Scoreboard &board) { sf::Event _event; - // keypress detection while (window.pollEvent(_event)) { switch (_event.type) { @@ -99,14 +100,14 @@ class Hero : public Actor { tDirection = rightTexture; rightArrowPressed = true; if (onRightStair) { - moveOn({ x_move_speed, -x_move_speed }); // up right + moveOn({ X_MOVE_SPEED, -X_MOVE_SPEED }); // up right } else if (onLeftStair) { - moveOn({ x_move_speed, x_move_speed }); // down right + moveOn({ X_MOVE_SPEED, X_MOVE_SPEED }); // down right } else { if (collision != rColl && collision == bColl) { - moveOn({ x_move_speed, 0 }); // right + moveOn({ X_MOVE_SPEED, 0 }); // right } } } @@ -115,14 +116,14 @@ class Hero : public Actor { tDirection = leftTexture; leftArrowPressed = true; if (onLeftStair) { - moveOn({ x_move_speed, -x_move_speed }); // up left + moveOn({ X_MOVE_SPEED, -X_MOVE_SPEED }); // up left } else if (onRightStair) { - moveOn({ x_move_speed, x_move_speed }); // down left + moveOn({ X_MOVE_SPEED, X_MOVE_SPEED }); // down left } else { if (collision != lColl && collision == bColl) { - moveOn({ x_move_speed, 0 }); // left + moveOn({ X_MOVE_SPEED, 0 }); // left } } } @@ -137,9 +138,6 @@ class Hero : public Actor { if (!onLeftStair && !onRightStair) inJump = true; } - if (sf::Keyboard::isKeyPressed(sf::Keyboard::H)) { - respawn(); - } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) { exit(1); } diff --git a/firstSFML/Info.h b/firstSFML/Info.h index d8c48ce..3f5e711 100644 --- a/firstSFML/Info.h +++ b/firstSFML/Info.h @@ -14,6 +14,7 @@ class Scoreboard { int score, topScore; string str1 = "SCORE-", str2 = " HI-", str3 = " REST-0", str_score, str_top_score, str_rest; // 17 letters + 17 numbers public: + // initialize gameData, set font size, color, outline... Scoreboard() { score = 0; topScore = 0; @@ -39,20 +40,22 @@ class Scoreboard { lives = LIVES_CONST; fillTable(); } + // convert ints into strings and add them to the table void fillTable() { - stringstream ss; - ss.setf(ios::right); - ss.width(6); + stringstream ss; // stream + ss.setf(ios::right); // formatting to make 000000 + ss.width(6); ss.fill('0'); ss << score; - str_score = ss.str(); - if (score >= topScore) { + str_score = ss.str(); // to get data stored in ss + if (score >= topScore) { // increase top score topScore = score; str_top_score = str_score; } - str_rest = to_string(lives); - gameData.setString(str1 + str_score + str2 + str_top_score + str3 + str_rest); + str_rest = to_string(lives); // int -> string + gameData.setString(str1 + str_score + str2 + str_top_score + str3 + str_rest); // make sentence } + // draw game info on to the screen void drawTo(sf::RenderWindow &window) { window.draw(gameData); } diff --git a/firstSFML/Log.h b/firstSFML/Log.h index 60cedaa..f486f85 100644 --- a/firstSFML/Log.h +++ b/firstSFML/Log.h @@ -1,59 +1,26 @@ #pragma once #include "pch.h" #include -#include #include #include using namespace std; -//typedef enum log_type { log_none, log_error, log_warning, log_info, log_debug } t_log_type; - -/*class Log { - static int m_logLevel; - time_t t = time(NULL); - -public: - static void setLevel(t_log_type logLevel) { - m_logLevel = logLevel; - } - Log& operator<<(t_log_type manip) /// setiosflags, resetiosflags - { - //manip(m_stream); - return *this; - } - static string printTime() { - time_t rawtime; - tm * timeInfo; - char buffer[26]; - - time(&rawtime); - timeInfo = localtime(&rawtime); - - strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", timeInfo); - return buffer; - } - static void write(t_log_type log_level, string message) { - if (log_level <= m_logLevel) { - char buffer[255]; - //clog << '[' << log_level << ']' << message << endl; - clog << sprintf(buffer, "%s [%d] %s", printTime().c_str(), log_level, message.c_str()) << endl; - } - } -}; -*/ class Logger { + stringstream m_stream; // storage + int m_logLevel; // current output logging level + int m_defLogLevel; // in no logging level entered, then m_logLevel = m_defLogLevel + int m_maxLogLevel; // filter messages with logging level > than m_maxLogLevel public: - typedef ostream& (*ManipFn)(ostream&); - typedef ios_base& (*FlagsFn)(ios_base&); - - enum LogLevel { + typedef ostream& (*ManipFn)(ostream&); // means we will get manipulators as function arguments + // enum with logging levels + enum LogLevel { ERR, WARN, INFO, DEBUG }; - + // initialize default and max log levels Logger(LogLevel defLogLevel, LogLevel maxLogLevel) { m_defLogLevel = m_logLevel = defLogLevel; m_maxLogLevel = maxLogLevel; @@ -64,13 +31,14 @@ class Logger { m_stream << output; return *this; } + // set new max log level void ChangeMaxLogLevel(int step) { m_maxLogLevel = step; - (*this)(INFO) << "Max logger mode - " << m_maxLogLevel << endl; + (*this)(INFO) << "Max logger mode - " << m_maxLogLevel << endl; // message } // to finish getting input and flush it into the stream Logger& operator<<(ManipFn manip) { // endl, flush, setw, setfill, etc. - manip(m_stream); + manip(m_stream); // apply manipulators to our string stream if (manip == static_cast(std::flush) || manip == static_cast(endl)) @@ -78,22 +46,15 @@ class Logger { return *this; } - // get format flags - Logger& operator<<(FlagsFn manip) { // setiosflags, resetiosflags - manip(m_stream); - return *this; - } // get log level Logger& operator()(LogLevel e) { m_logLevel = e; return *this; } - + // write message to the console / file ... void flush() { /* - m_stream.str() has your full message here. - Good place to prepend time, log-level. - Send to console, file, socket, or whatever you like here. + m_stream.str() has full message here. */ if (m_logLevel <= m_maxLogLevel) { @@ -101,13 +62,7 @@ class Logger { } m_logLevel = m_defLogLevel; // if no log level entered - m_stream.str(std::string()); - m_stream.clear(); + m_stream.str(string()); // clear buffer + m_stream.clear(); // clear the error state } - -private: - stringstream m_stream; // storage - int m_logLevel; - int m_defLogLevel; - int m_maxLogLevel; }; \ No newline at end of file diff --git a/firstSFML/Map.h b/firstSFML/Map.h index 72fd429..b0755e1 100644 --- a/firstSFML/Map.h +++ b/firstSFML/Map.h @@ -26,13 +26,14 @@ class Controle : public Block { map_part = i; } //noTexture = 0, wall = 1, stairLeftUnder = 2, stairLeft = 3, stairLeftTop = 4, stairRightUnder = 5, stairRight = 6, stairRightTop = 7, hardWall = 8 + // read file and init blocks with sprites void openMap(Block **newMap, string level) { ifstream mapPtr(level); if (!mapPtr) { myLog(Logger::ERR) << "error opening file - not exists" << endl; exit(1); } - mapPtr >> x_curr_map_size >> y_curr_map_size; + mapPtr >> x_curr_map_size >> y_curr_map_size; // get map sizes myLog(Logger::INFO) << "map size is " << x_curr_map_size << " x " << y_curr_map_size << endl; char ch; for (int j = 0; j < y_curr_map_size; j++) { @@ -115,9 +116,9 @@ class Controle : public Block { } case '*': { newMap[i][j].create(coin, current_level); - if (i < MAP_SIZE_X) + if (i < MAP_SIZE_X) // first map part newMap[i][j].setPos({ i * BLOCK_SIZE_X, j * BLOCK_SIZE_Y }); - else + else // second map part newMap[i][j].setPos({ (i - MAP_SIZE_X) * BLOCK_SIZE_X, j * BLOCK_SIZE_Y }); break; } @@ -129,9 +130,10 @@ class Controle : public Block { } mapPtr.close(); } + // draw all map to the screen void drawTo(sf::RenderWindow &window, Block **newMap) { - int iLimit = (map_part == 1) ? MAP_SIZE_X : x_curr_map_size; - int iBegin = (map_part == 1) ? 0 : MAP_SIZE_X - 1; + int iLimit = (map_part == 1) ? MAP_SIZE_X : x_curr_map_size; // set limitation depending on map part + int iBegin = (map_part == 1) ? 0 : MAP_SIZE_X - 1; // set limitation depending on map part for (int j = 0; j < y_curr_map_size; j++) { // all except stair parts for (int i = iBegin; i < iLimit; i++) { diff --git a/firstSFML/Mummy.h b/firstSFML/Mummy.h index 48fe4ce..db4573c 100644 --- a/firstSFML/Mummy.h +++ b/firstSFML/Mummy.h @@ -2,14 +2,13 @@ #include "pch.h" class Mummy : public Actor { - enum mummyMovement move; string mummyTexture[2][3] = { { "images/mummy_left_0.png", "images/mummy_left_1.png", "images/mummy_left_2.png" }, { "images/mummy_right_0.png", "images/mummy_right_1.png", "images/mummy_right_2.png" } }; - t_textureDir tDirection = leftTexture; - int textureCounter = 1; + t_textureDir tDirection = leftTexture; // enum to choose part of the first dimention of the texture array + int textureCounter = 1; // counter to choose texture in the second dimention of the texture array float lastPositionX; - const float deltaPositionX = 10.f; public: + // initialize sprite whith a texture Mummy(sf::Vector2f size, string fname) : Actor(size) { // object.setFillColor(sf::Color::White); if (!texture.loadFromFile(fname)) { @@ -21,6 +20,7 @@ class Mummy : public Actor { skin = bot; sprite.setScale({ size.x / texture.getSize().x , size.y / texture.getSize().y }); } + // change textures while moving void chooseTexture() { if (inJump == true) { this->texture.loadFromFile(mummyTexture[tDirection][0]); @@ -32,13 +32,14 @@ class Mummy : public Actor { else { this->texture.loadFromFile(mummyTexture[tDirection][textureCounter]); } - if (abs(lastPositionX - this->getCoord().x) >= deltaPositionX) { + if (abs(lastPositionX - this->getCoord().x) >= CHANGE_TEXTURE_DELTA_X) { lastPositionX = this->getCoord().x; textureCounter++; if (textureCounter >= 3) textureCounter = 0; } } + // auto move mummy void autoMoveOn(sf::Vector2f distance) { if (rand() % 700 == 2) dir = (dir == toleft) ? toright : toleft; diff --git a/firstSFML/Sound.h b/firstSFML/Sound.h index a3077a2..c06eb62 100644 --- a/firstSFML/Sound.h +++ b/firstSFML/Sound.h @@ -2,18 +2,21 @@ #include "pch.h" class GameMusic { - sf::SoundBuffer buffer; + sf::SoundBuffer buffer; // pointer to the sound file sf::Sound sound; public: + // initialize buffer and sound GameMusic(string path, bool bloop) { if (!buffer.loadFromFile(path)) myLog(Logger::ERR) << "Failed to load sound" << endl; sound.setBuffer(buffer); sound.setLoop(bloop); } + // start playing sound void playSound() { sound.play(); } + // stop playing sound void stopSound() { sound.stop(); } diff --git a/firstSFML/firstSFML.cpp b/firstSFML/firstSFML.cpp index bc22ab7..ac2166d 100644 --- a/firstSFML/firstSFML.cpp +++ b/firstSFML/firstSFML.cpp @@ -24,7 +24,7 @@ void botCheckCollision(Actor &bot, Block **map, int mapPart) { bot.setDir(toright); bot.annulateCollision(); } - +// show beginning, ending screens, wait for space or close void changeScreen(sf::RenderWindow &window, string sceneName) { sf::Event _event; sf::Texture sceneTexture; @@ -52,7 +52,7 @@ void changeScreen(sf::RenderWindow &window, string sceneName) { cout << "closing" << endl; exit(0); } - endGamePlayer.autoMoveOn({ x_move_speed, 0 }, toright); + endGamePlayer.autoMoveOn({ X_MOVE_SPEED, 0 }, toright); window.clear(); window.draw(sceneScreen); endGamePlayer.drawTo(window); @@ -75,7 +75,7 @@ void changeScreen(sf::RenderWindow &window, string sceneName) { Sleep(50); } } - +// play sounds, draw player, map, bots, load levels int gamePlay(sf::RenderWindow &window, Scoreboard &board) { window.clear(); Controle level; @@ -96,7 +96,6 @@ int gamePlay(sf::RenderWindow &window, Scoreboard &board) { map[i] = new Block[MAP_SIZE_Y]; } lives = LIVES_CONST; - player.respawn(); changeScreen(window, "images/title_screen.png"); soundStartGame.stopSound(); soundPlaying.playSound(); @@ -129,6 +128,7 @@ int gamePlay(sf::RenderWindow &window, Scoreboard &board) { myLog(Logger::INFO) << "NEXT LEVEL" << endl; switch (level.current_level) { case 0: { // first level + // new respawn positions player.setRespawn({ 16, 10 }); player.respawn(); bot1.setRespawn({ 7, 2 }); @@ -145,7 +145,7 @@ int gamePlay(sf::RenderWindow &window, Scoreboard &board) { } case 1: { // second level soundNextMap.playSound(); - loadedNextLevel = true; + loadedNextLevel = true; // to show map and start playing intro music board.addPoint(2000); player.setRespawn({ 16, 9 }); player.respawn(); @@ -191,15 +191,15 @@ int gamePlay(sf::RenderWindow &window, Scoreboard &board) { } player.controle(window, board); // get user input - bot1.autoMoveOn({ x_move_speed, 0 }); - bot2.autoMoveOn({ x_move_speed, 0 }); - bot3.autoMoveOn({ x_move_speed, 0 }); + bot1.autoMoveOn({ X_MOVE_SPEED, 0 }); + bot2.autoMoveOn({ X_MOVE_SPEED, 0 }); + bot3.autoMoveOn({ X_MOVE_SPEED, 0 }); botCheckCollision(bot1, map, level.getMapPart()); botCheckCollision(bot2, map, level.getMapPart()); botCheckCollision(bot3, map, level.getMapPart()); player.xMap = player.getSenter().x / BLOCK_SIZE_X; - player.yMap = player.getSenter().y / BLOCK_SIZE_X; + player.yMap = player.getSenter().y / BLOCK_SIZE_Y; if (level.getMapSizeX() > 32) { // if map consists of 2+ parts if (player.xMap == 31 && level.getMapPart() == 1) { // to second part @@ -239,7 +239,7 @@ int gamePlay(sf::RenderWindow &window, Scoreboard &board) { if (level.getMapPart() == 2) { // second half of map array player.xMap += 32; } - //clog << "xMap = " << player.xMap << " yMap = " << player.yMap << endl; + myLog(Logger::INFO) << "xMap = " << player.xMap << " yMap = " << player.yMap << endl; player.annulateCollision(); // if won't be any collisions, value won't change from 'no' @@ -276,15 +276,9 @@ int gamePlay(sf::RenderWindow &window, Scoreboard &board) { bot3.drawTo(window); player.drawTo(window); board.drawTo(window); - - //Denys - gravity_speed = GRAVITY_SPEED_CONST; - x_move_speed = X_MOVE_SPEED_CONST; // add const 1 for alex - jump_change_step = JUMP_CHANGE_STEP_CONST; - window.display(); } - // game ended with win or lives ended + // game ended with lives ended soundPlaying.stopSound(); for (int i = 0; i < MAX_MAP_SIZE_X; i++) { delete[] map[i]; // delete sub-array @@ -300,14 +294,13 @@ int gamePlay(sf::RenderWindow &window, Scoreboard &board) { } int main(int argc, char* argv[]) { - if (argc == 2) { + if (argc == 2) { // get log level as cmd argument myLog.ChangeMaxLogLevel(atoi(argv[1])); } Scoreboard board; sf::RenderWindow window(sf::VideoMode(WINDOW_SIZE_X, WINDOW_SIZE_Y), "King's Valley", sf::Style::Default); - //window.setFramerateLimit(100); - window.setFramerateLimit(60); + window.setFramerateLimit(FPS_LOCK); while (true) { board.annulatePoint();