I looked for some tutorials for game development, I found one where I'm supposed to create a pong clone, but I can't even create the window, I get the following:
"Unhandled exception at 0xEEFFEE01 in Pang.exe: 0xC0000005: Access violation reading location 0xEEFFEE01."
I'm using SFML 1.6 and Visual Studio 2013.
Here is my code.
Game.cpp
#include "stdafx.h"
#include "Game.h"
void Game::Start(void)
{
if (_gameState != Uninitialized)
return;
_mainWindow.Create(sf::VideoMode(1024, 768, 32), "Pang!");
_gameState = Game::Playing;
while (!IsExiting())
{
GameLoop();
}
_mainWindow.Close();
}
bool Game::IsExiting()
{
if (_gameState == Game::Exiting)
return true;
else
return false;
}
void Game::GameLoop()
{
sf::Event currentEvent;
while (_mainWindow.GetEvent(currentEvent))
{
switch (_gameState)
{
case Game::Playing:
{
_mainWindow.Clear(sf::Color(255, 0, 0));
_mainWindow.Display();
if (currentEvent.Type == sf::Event::Closed)
{
_gameState = Game::Exiting;
}
break;
}
}
}
}
Game::GameState Game::_gameState = Uninitialized;
sf::RenderWindow Game::_mainWindow;
Game.h
#pragma once
#include "SFML/Window.hpp"
#include "SFML/Graphics.hpp"
class Game
{
public:
static void Start();
private:
static bool IsExiting();
static void GameLoop();
enum GameState {
Uninitialized, ShowingSplash, Paused,
ShowingMenu, Playing, Exiting
};
static GameState _gameState;
static sf::RenderWindow _mainWindow;
};
Pang.cpp
#include "stdafx.h"
#include "Game.h"
int _tmain(int argc, _TCHAR* argv[])
{
Game::Start();
return 0;
}
I know there's some code that has nothing to do with my problem, the error occurs when it reaches this line in Game.cpp
_mainWindow.Display();
I'm new on this so any help, any good tutorials or starting point to start learning will be good.
Some general SFML advice: Update to SFML 2.0, especially if you are using VS2013. Here are the official SFML tutorials http://www.sfml-dev.org/tutorials/2.0/
It looks like you just copied your code from here http://en.sfml-dev.org/forums/index.php?topic=10855.0 if this is true you should have realized that the code did not work, if not then the person who copied the code and used it in their tutorial should have noticed, and the fact they didn't is worrying about the state of the rest of their tutorials
Okay so the issue is you can't have a static RenderWindow, and with that your entire game class should not be static, it just isn't good programming practice. What you need to do is remove the static identifier from every declaration in your Game.h header file. For instance:
This
static void Start();
Needs to look like this
void Start();
Next, your Pang.cpp should look like this
//#include "stdafx.h" you don't need this precompiled header
#include "Game.h"
int main(int argc, char* argv[])
{
Game myGame;
myGame.Start();
return 0;
}
Related
I want to display my player in the window but my player sprite is not showing in the window. I am new to c++. I want to learn classes, inheritence, composition, etc in this way.I have 3 files Player.cpp, Game.cpp and main.cpp. I am using main.cpp to call Game.cpp using a fuction called Run().
Got nothing to try.
Player.cpp
#include "Player.hpp"
#include "string.h"
#include <iostream>
void Player::initPlayer()
{
const char* playerTexturePath = "/Users/don/Desktop/sfmlgames/game1/img/MCmid.png";
if(!mPlayerTexture.loadFromFile(playerTexturePath))
{
std::cout << "mPlayerTexturePath not found!!" << std::endl;
}
mPlayerSprite.setTexture(mPlayerTexture);
mPlayerSprite.setPosition(100.f, 100.f);
mPlayerSprite.setScale(1.f, 1.f);
}
void Player::draw_player(sf::RenderWindow &win)
{
win.draw(mPlayerSprite);
}
Game.cpp
#include "Game.hpp"
#include <iostream>
Player player1;
//Constructor: Create a window and Player
Game::Game() : mWindow(sf::VideoMode(640, 480), "Game")
{
//Frame rate 60
mWindow.setFramerateLimit(60);
player1.initPlayer();
}
//Game loop
void Game::Run()
{
while(mWindow.isOpen())
{
render();
events();
update();
}
}
void Game::events()
{
sf::Event event;
while (mWindow.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
mWindow.close();
}
}
}
void Game::update()
{
}
void Game::render()
{
mWindow.clear(sf::Color::Red);
player1.draw_player(mWindow);
mWindow.display();
}
main.cpp
#include "Game.hpp"
int main()
{
Game game;
game.Run();
}
I don't think I will need to give code to hpp files.
The problem was with image I dont know why. I used another image and it worked fine.
I encountered a strange bug using SDL_PollEvent to detect an SDL_Quit event. Whenever I click the X on the window it works fine and ends the program but whenever I hold down the X button it pauses the execution of the program. Any idea why this is happening, and is there a way around it?
Here is my code:
main.cpp
#include "Game.h"
int main() {
Game* game = nullptr;
while(game->running) {
game->checkForClose();
return 0;
}
Game.h
#ifndef GAME_H_
#define GAME_H_
#include "SDL.h"
class Game {
public:
Game();
~Game();
void checkForClose();
static bool running;
static SDL_Event event;
};
#endif
Game.cpp
#include "Game.h"
#include <iostream>
void Game::checkForClose() {
SDL_PollEvent(&event);
switch (event.type) {
case SDL_QUIT:
running = false;
std::cout << "Program Terminated!" << std::endl;
break;
default:
break;
}
}
P.S. I am on MacOS
I'm completely unsure of why I'm getting this error in VS2012 when I run my program. Visual Studio seemed to direct the problem towards sf::RenderWindow Articx::window; in Articx.cpp
Unhandled exception at 0x777122D2 (ntdll.dll) in ArticxEngine.exe:
0xC0000005: Access violation writing location 0x00000004.
Code Articx.h
#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
class Articx
{
public:
static void Start();
private:
static void GameLoop();
static bool isExiting();
enum ScreenState {before, splash1, splash2, splash3, menu, pause, playing, exit};
static ScreenState currentState;
static sf::RenderWindow window;
};
Code Articx.cpp
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <iostream>
#include <string>
#include "Articx.h"
inline void Message(char message[]);
inline void CallError(int code, char message[]);
Articx::ScreenState Articx::currentState = Articx::before;
sf::RenderWindow Articx::window;
void Articx::Start()
{
Message("Articx Engine 1.0 Initializing...");
if(currentState != before)
return;
window.create(sf::VideoMode(800,600,32), "Articx Engine 1.0");
currentState = playing;
while (!isExiting())
{
Message("Engine Initialized");
Articx::GameLoop();
}
window.close();
}
bool Articx::isExiting()
{
if(currentState == exit)
return true;
else
return false;
}
void Articx::GameLoop()
{
sf::Event currentEvent;
while ( window.pollEvent(currentEvent) )
{
switch(currentState)
{
case Articx::playing:
{
window.clear(sf::Color(0,0,0));
window.display();
if ( currentEvent.type == sf::Event::Closed )
currentState = exit;
break;
}
}
}
window.display();
}
inline void CallError(int code, char message[])
{
std::cout << "ERROR CODE - " << code << std::endl << message << std::endl << "Will now exit..." << std::endl;
system("PAUSE");
}
inline void Message(char message[])
{
std::cout << "AX-MESSAGE: " << message << std::endl;
}
Code main.cpp
#include "Articx.h"
using namespace std;
int main(int argc, char** argv)
{
Articx::Start();
return 0;
}
The "Bottom Line" Reason
The reason for the unhandled exception is because you defined Articx::window as a static variable.
The Technical Explanation
The exception was thrown because constructing an sf:RenderWindow invokes the following constructors in this order:
RenderWindow::RenderWindow()
Window::Window()
GlResource::GlResource()
The GlResource::GlResource() constructor attempts to lock a global mutex:
namespace
{
// OpenGL resources counter and its mutex
unsigned int count = 0;
sf::Mutex mutex;
}
namespace sf
{
////////////////////////////////////////////////////////////
GlResource::GlResource()
{
{
// Protect from concurrent access
Lock lock(mutex);
// If this is the very first resource, trigger the global context initialization
if (count == 0)
priv::GlContext::globalInit();
// Increment the resources counter
count++;
}
// Now make sure that there is an active OpenGL context in the current thread
priv::GlContext::ensureContext();
}
The problem is that both your Articx::window and SFML's sf::Mutex mutex are global/static variables that are constructed at program initialization time. Which one gets constructed first? In your case your window was constructed first, so the GlResource::GlResource() constructor attempted to lock an invalid sf::Mutex. Because the order of construction of global/static variables can be unpredictable, it is best to create your sf::RenderWindow object in a non-global location.
The Solution
In main.cpp, create your sf::RenderWindow object within main(), passing a reference to window via Articx::Start():
#include "Articx.h"
using namespace std;
int main(int argc, char** argv)
{
sf::RenderWindow window;
Articx::Start(window);
return 0;
}
In Articx.h, remove the static member variable window, and expand Start() and Gameloop() to accept an sf::RenderWindow reference:
#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
class Articx
{
public:
static void Start(sf::RenderWindow &window);
private:
static void GameLoop(sf::RenderWindow &window);
static bool isExiting();
enum ScreenState {before, splash1, splash2, splash3, menu, pause, playing, exit};
static ScreenState currentState;
};
In Articx.cpp, remove the global definition of window and modify Start() and Gameloop() to accept and use the passed sf::RenderWindow reference:
void Articx::Start(sf::RenderWindow &window)
{
Message("Articx Engine 1.0 Initializing...");
if(currentState != before)
return;
window.create(sf::VideoMode(800,600,32), "Articx Engine 1.0");
currentState = playing;
while (!isExiting())
{
Message("Engine Initialized");
Articx::GameLoop(window);
}
window.close();
}
. . .
void Articx::GameLoop(sf::RenderWindow &window)
{
. . .
}
Running it now displays the window correctly:
The window seems to have an endless loop printing "Engine Initialized", but I leave that to you :-).
I recently got started trying to use SFML. For some reason my simple program will not render the window. I've tried throwing everything into main to see if there was an error in my code that had to do with multiple files etc. but to no avail.
I'll launch my program and nothing will appear.
What's the problem?
//main.h
#ifndef MAIN_H
#define MAIN_H
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <iostream>
#include <fstream>
using namespace std;
using namespace sf;
class game
{
public:
void startLoop(int SCREEN_W, int SCREEN_H, string SCREEN_NAME);
void log(const string logging);
game()
{
QUIT = false;
pendingFile.open("Log.txt", ios::out);
pendingFile << "---Brain Bread Log---";
}
~game()
{
pendingFile.close();
}
private:
bool QUIT;
ofstream pendingFile;
};
#endif
//main.cpp
#include "main.h"
void game::log(const string logging)
{
pendingFile << logging;
}
void game::startLoop(int SCREEN_W, int SCREEN_H, string SCREEN_NAME)
{
Window Game(VideoMode(SCREEN_W, SCREEN_H, 32), SCREEN_NAME);
while(QUIT == false)
{
Game.Display();
}
}
int main(int argc, char* argv[])
{
game gameObj;
gameObj.startLoop(800, 600, "Brain Bread");
return 0;
}
I tried your code and it behaves exactly as I expect it to - that is to say that an iconless window with a black body pops up and it doesn't respond to events. Is that what you're getting? If not, you might need to rebuild SFML.
You might want to try introducing event-handling so that your startLoop looks more like this:
void game::startLoop(int SCREEN_W, int SCREEN_H, string SCREEN_NAME)
{
// Init stuff
while (Game.IsOpened())
{
sf::Event newEvent;
while (Game.GetEvent(newEvent))
{
// Process event
}
// Do graphics stuff
Game.Display();
}
}
For some reason SDL refuses to render an image. I don't see why and it's really bogging down my progress on a 2d game i'm developing. Everything is linked properly and such. Here's my code:
//main.cpp
#include "main.h"
void game::createWindow(const int SCREEN_W, const int SCREEN_H, const char* SCREEN_NAME)
{
buffer = SDL_SetVideoMode(SCREEN_W, SCREEN_H, 0, NULL);
SDL_WM_SetCaption(SCREEN_NAME, NULL);
}
void game::enterLoop()
{
while(Running == true)
{
SDL_BlitSurface(zombie, NULL, buffer, NULL);
SDL_Flip(buffer);
while(SDL_PollEvent(&gameEvent))
{
if(gameEvent.type == SDL_QUIT)
{
Running = false;
}
}
}
}
void game::loadContent()
{
zombie = SDL_LoadBMP("zombie.bmp");
}
int main(int argc, char* argv[])
{
game gameObj;
SDL_Init(SDL_INIT_EVERYTHING);
gameObj.createWindow(960, 600, "uShootZombies");
gameObj.loadContent();
gameObj.enterLoop();
SDL_Quit();
return 0;
}
//main.h
#include <SDL.h>
#include <fstream>
#include <string>
using namespace std;
class game
{
public:
void createWindow(const int SCREEN_W, const int SCREEN_H, const char* SCREEN_NAME);
void enterLoop();
void loadContent();
game()
{
Running = true;
}
~game()
{
SDL_FreeSurface(buffer);
SDL_FreeSurface(background);
SDL_FreeSurface(player);
SDL_FreeSurface(zombie);
}
private:
SDL_Surface* buffer;
SDL_Surface* background;
SDL_Surface* player;
SDL_Surface* zombie;
SDL_Event gameEvent;
bool Running;
};NU
I just copied all of your code to use in code::blocks and it works fine.
Of course I was using my own .bmp file which I named "zombie.bmp"
Are you sure your .bmp file is ok?
Be aware that if you originally save it as a .jpeg file or something like that, then simply renamed it to .bmp, it won't work (And it won't throw an error either)
It must be originally saved as a bmp.
That is all I can think of.
It seems that Sour Lemon has already solved your problem, but I still thought it would be worth pointing out that the above code doesn't perform any checks to make sure that your zombie image was actually loaded correctly.
You should be doing something like this:
void game::loadContent()
{
zombie = SDL_LoadBMP("zombie.bmp");
if (zombie == NULL) {
ReportError(SDL_GetError());
}
}