In an effort to refactor, I recently moved the majority of the code in my main method into it's own Game class. However, upon doing so I appear to have broken a number of my window.draw() statements, without having them give any particular error, but rather, raising a EXC_BAD_ACCESS (code: EXC_I386_GPFLT) exception when I step through them in debug. Further research (
https://bit.ly/2tXDEV3) indicates that this could mean that I'm using a "non-canonical pointer", but I'm relatively new to C++ development so I would not know where to even begin with this?
main.cpp:
#include "Game.h"
Game *game = nullptr;
int main()
{
game = new Game;
game->setUp();
game->update();
return 0;
}
Game.h:
#include <SFML/Graphics.hpp>
class Game {
public:
void setUp();
void update();
private:
sf::RenderWindow window;
sf::Vector2u screenDimensions;
sf::Sound music;
sf::Text title, score;
int textAlpha = 256, playerScore = 0;
std::vector<Ring> rings;
sf::View backgroundView, playerView;
bool quitGame = false;
void textSetUp(sf::Text &text, std::string string, sf::Font font, unsigned int characterSize, sf::Color fillColour, sf::Text::Style style, sf::Vector2f position);
void textSetUp(sf::Text &text, std::string string, sf::Font font, unsigned int characterSize, sf::Color fillColour, sf::Text::Style style, sf::Vector2f position, sf::Color outlineColour, float outlineThickness);
};
Game.cpp:
#include "Game.h"
void Game::setUp() {
screenDimensions.x = 1920;
screenDimensions.y = 1280;
// Window:
window.create(sf::VideoMode(screenDimensions.x, screenDimensions.y), "Sk-iver", sf::Style::Titlebar | sf::Style::Close | sf::Style::Resize);
window.setPosition(sf::Vector2i(200, 150));
window.setKeyRepeatEnabled(false); // TODO investigate
window.setVerticalSyncEnabled(true);
window.setFramerateLimit(60);
// Music:
sf::SoundBuffer musicBuffer;
if(!musicBuffer.loadFromFile("Resources/Sounds/nice_music.ogg"))
std::cout << "ERROR: could not load audio file from file path" << std::endl;
music.setBuffer(musicBuffer);
music.setLoop(true);
music.setVolume(20);
music.play();
// Title & Score Font assignment:
sf::Font font;
if(!font.loadFromFile("Font/Arial_Unicode.ttf"))
std::cout << "ERROR: Could not load font file." << std::endl;
// Title & Score Colour assignment:
sf::Color scoreColour = titleColour = sf::Color::White;
scoreColour.a = 150;
// Title:
std::string titleString = "Sk-iver";
sf::Vector2f titlePosition((screenDimensions.x - title.getGlobalBounds().width) / 2,
(screenDimensions.y - title.getGlobalBounds().height) / 2);
textSetUp(title, titleString, font, 500, titleColour, sf::Text::Bold, titlePosition);
// Score:
sf::Vector2f scorePosition(screenDimensions.x - score.getGlobalBounds().width, 0);
textSetUp(score, std::to_string(playerScore), font, 80, scoreColour, sf::Text::Italic, scorePosition, sf::Color::Black, 5);
// Background View:
backgroundView.reset(sf::FloatRect(0, 0, screenDimensions.x, screenDimensions.y));
backgroundView.setViewport(sf::FloatRect(0, 0, 1.0f, 1.0f));
// Player View:
playerView.reset(sf::FloatRect(0, 0, screenDimensions.x, screenDimensions.y));
playerView.setViewport(sf::FloatRect(0, 0, 1.0f, 1.0f));
}
// text set up for title Text
void Game::textSetUp(sf::Text &text, std::string string, sf::Font font, unsigned int characterSize, sf::Color fillColour, sf::Text::Style style, sf::Vector2f position) {
text.setString(string);
text.setFont(font);
text.setCharacterSize(characterSize);
text.setFillColor(fillColour);
text.setStyle(style);
text.setPosition(position);
}
// text set up for score Text
void Game::textSetUp(sf::Text &text, std::string string, sf::Font font, unsigned int characterSize, sf::Color fillColour, sf::Text::Style style, sf::Vector2f position, sf::Color outlineColour, float outlineThickness) {
text.setString(string);
text.setFont(font);
text.setCharacterSize(characterSize);
text.setFillColor(fillColour);
text.setStyle(style);
text.setPosition(position);
text.setOutlineColor(outlineColour);
text.setOutlineThickness(outlineThickness);
}
void Game::update() {
// todo find a more elegant solution for this
Diver player = Diver(window.getSize());
Background background = Background(window.getSize());
while(!quitGame) // beginning of game loop
{
// Get player inputs:
quitGame = HandleEvents(music, window);
window.setView(backgroundView);
// Background (update & draw):
background.update();
background.draw(window);
// Rings (generate, update & draw):
if (clock.getElapsedTime().asSeconds() > 9)
{
Ring ring = Ring(window.getSize());
rings.emplace_back(ring);
clock.restart();
}
// todo make two vectors, one for all rings where getStage()<= 1, and those that == 2
for (auto &ring : rings)
{
if(ring.getStage() <= 1)
{
int tempScore = ring.update(player);
// Score update
if(tempScore) // i.e. if tempScore != 0
{
playerScore += tempScore;
score.setString(std::to_string(playerScore));
score.setPosition(screenDimensions.x - score.getGlobalBounds().width, 0);
}
ring.draw(window);
}
}
// The Player (update & draw):
window.setView(playerView);
player.getInputs();
frameCounter = player.update(clock, frameCounter, frameSpeed);
player.draw(window);
// slowly fades out title - todo: needs to be in it's own title object
if (textAlpha > 5) // means that title is no longer drawn once no longer visible
{
if (clock.getElapsedTime().asSeconds() > 5)
{
titleColour.a = static_cast<sf::Uint8>(textAlpha--);
title.setFillColor(titleColour);
}
window.draw(title);
}
else
{
window.draw(score);
}
window.display();
window.clear();
}
}
Note: music is also not working, which I have also not altered and believe may be related, but cannot prove this atm. Otherwise, most other sprites/shapes called in their own draw functions are drawing as normal.
Any help with this would be greatly GREATLY appreciated!