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.
Related
im currently making on my 2D game and i have a error that i dont understand, here is screenshot of the rror:
enter image description here
here is code for main:
#include "Game.h"
#include "Player.h"
void Run(RenderWindow &window, Sprite &player, Texture &PlayerTex);
int main(RenderWindow &window, Sprite &player, Texture &PlayerTex) {
Run(window, player, PlayerTex);
return 0;
}
void InitWindow() {
RenderWindow window(VideoMode(1920, 1080), "Discord Game");
}
void Update() {
}
void Render(RenderWindow &window, Sprite &player) {
player.setScale(0.3f, 0.3f);
window.clear(Color::White);
window.draw(player);
window.display();
}
void Run(RenderWindow &window, Sprite &player, Texture &PlayerTex) {
InitWindow();
while (window.isOpen()) {
Event sfEvent;
while (window.pollEvent(sfEvent)) {
if (sfEvent.type == Event::Closed)
window.close();
}
Update();
Render(window, player);
Player P;
P.PlayerMovement(player);
}
}
code for Player.H:
#pragma once
#include "Game.h"
class Player {
public:
Sprite player;
Texture PlayerTex;
void PlayerTexture(Sprite &Player, Texture &PlayerTex);
void PlayerMovement(Sprite &Player);
};
code for Player.cpp:
#include "Game.h"
#include "Player.h"
void Player::PlayerTexture(Sprite& player, Texture& PlayerTex) {
PlayerTex.loadFromFile("textures/Player/PlayerFront.png");
player.setTexture(PlayerTex);
}
void Player::PlayerMovement(Sprite &player) {
if (Keyboard::isKeyPressed(Keyboard::A)) {
player.move(-5.f, 0.f);
}
if (Keyboard::isKeyPressed(Keyboard::D)) {
player.move(5.f, 0.f);
}
if (Keyboard::isKeyPressed(Keyboard::W)) {
player.move(0.f, -5.f);
}
if (Keyboard::isKeyPressed(Keyboard::S)) {
player.move(0.f, 5.f);
}
}
and then i have Game.H just to include stuff and for the future, here is code for Game.h:
#pragma once
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Network.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <iostream>
using namespace sf;
class Game {
};
and then empty Game.cpp:
#include "Game.h"
I've been trying to make a sprite display in C++ SFML but with the use of classes. However, when I compile and run the program, nothing appears: there are no errors either.
(The only thing that happens in main is that a 'Game' object is created)
Game.h
#ifndef GAME_H
#define GAME_H
#include <SFML/Graphics.hpp>
#include "Player.h"
class Game
{
public:
Game();
private:
//Variables
sf::RenderWindow _mainWindow;
enum _gameState { Playing, Paused, Splash, Menu };
//Methods
void gameLoop();
};
#endif // GAME_H
Game.cpp
#include "Game.h"
#include "Player.h"
Game::Game() {
//Variables
_mainWindow.create(sf::VideoMode(960, 640), "Game", sf::Style::Titlebar | sf::Style::Close);
_mainWindow.setFramerateLimit(60);
//Start Game Loop
gameLoop();
}
void Game::gameLoop() {
Player player;
while(_mainWindow.isOpen()) {
sf::Event ev;
while(_mainWindow.pollEvent(ev)) {
if(ev.type == sf::Event::Closed)
_mainWindow.close();
if(ev.type == sf::Event::KeyPressed) {
if(ev.key.code == sf::Keyboard::Escape)
_mainWindow.close();
}
}
//Draw Stuff
_mainWindow.clear(sf::Color::White);
player.drawSprite(_mainWindow);
_mainWindow.display();
}
}
Player.h
#ifndef PLAYER_H
#define PLAYER_H
#include <SFML/Graphics.hpp>
#include <iostream>
class Player
{
public:
Player();
void drawSprite(sf::RenderWindow& window);
private:
bool loadSprite();
sf::Texture _playerTexture;
sf::Sprite _playerSprite;
};
#endif // PLAYER_H
Player.cpp
#include "Player.h"
#include "Game.h"
Player::Player()
{
if(!Player::loadSprite()){
return;
}
}
bool Player::loadSprite() {
sf::Texture _playerTexture;
if(!_playerTexture.loadFromFile("img/darkguy.png", sf::IntRect(32,32,32,32))) {
std::cout << "Failed to load player image" << std::endl;
return false;
} else {
sf::Sprite _playerSprite;
_playerSprite.setTexture(_playerTexture);
}
return true;
}
void Player::drawSprite(sf::RenderWindow& window) {
//sprite.setTextureRect(sf::IntRect(10, 10, 32, 32));
window.draw(_playerSprite);
std::cout << "Sprite Drawn Successfully" << std::endl;
}
You are declaring a new, local _playerSprite here:
} else {
sf::Sprite _playerSprite;
_playerSprite.setTexture(_playerTexture);
}
instead, use the existing class member:
} else {
_playerSprite.setTexture(_playerTexture);
}
You may want to drop the first line from this code as well, same issue:
bool Player::loadSprite()
{
sf::Texture _playerTexture; // <--- local redeclaration
From my memories: the texture must be a member of your class; it must exist while you are using it. In your code, _playerTexture is destroyed at the end of loadSprite(). Same problem for _playerSprite.
Edit:
You don't have to re-declare the member of your class in your methods :
bool Player::loadSprite() {
sf::Texture _playerTexture;
if(!_playerTexture.loadFromFile("img/darkguy.png", sf::IntRect(32,32,32,32))) {
std::cout << "Failed to load player image" << std::endl;
return false;
} else {
sf::Sprite _playerSprite;
_playerSprite.setTexture(_playerTexture);
}
return true;
}
Should be:
bool Player::loadSprite() {
if(!_playerTexture.loadFromFile("img/darkguy.png", sf::IntRect(32,32,32,32))) {
std::cout << "Failed to load player image" << std::endl;
return false;
} else {
_playerSprite.setTexture(_playerTexture);
}
return true;
}
(PS: Your code doesn't respect the SRP (Single Responsability Principle), Player doesn't have to display itself.)
you are drawing but not displaying the sprite for that do this
void Player::drawSprite(sf::RenderWindow& window) {
//sprite.setTextureRect(sf::IntRect(10, 10, 32, 32));
window.draw(_playerSprite);
std::cout << "Sprite Drawn Successfully" << std::endl;
//this is the display function
window.display()
}
I am working on a little project where I am trying to get a player in my 2D view (actually a circle) and let him move left to right, up and down flawless, also I want to be able to press 2 keys at ones so he moves sideways or something like that.
Also i want to be able to shoot with the player in a certain direction in a later state of the project (it could be important as of now)
I am doing this project because I want to learn how C++ OOP works.
The structure im having in my mind is simple :
Main > (Creates) > GameWindow
Main > (creates) > EntityManager > (creates) > Player
Player > (creates via) > EnitityManager > Gun
Gun > (Creates via) > EntityManager > Bullet
Player can :
Walk up/down/left/right
Shoot.
So to get to the code, This is what I have in my FirstGame.cpp
#include "stdafx.h"
#include "GameWindow.h"
#include "EntityManager.h"
int main()
{
// Create an entity manager
EntityManager::Instance();
// Display the window
GameWindow::Instance().Run();
}
in my GameWindow.h I have :
#pragma once
#include <SFML/Graphics.hpp>
using namespace sf;
class GameWindow
{
public:
static GameWindow& Instance()
{
static GameWindow instance;
return instance;
}
RenderWindow& GetRenderWindow();
void Run();
private:
static const int DEF_WIDTH = 1366;
static const int DEF_HEIGHT = 720;
GameWindow();
GameWindow(const GameWindow&);
GameWindow& operator=(const GameWindow&);
~GameWindow();
string windowTitle;
int windowWidth;
int windowHeight;
void Initialize();
void DisplayWindow();
void CheckWindowEvent();
};
and in my GameWindow.cpp
#include "StdAfx.h"
#include "GameWindow.h"
#include "Player.h"
#include "SFML\Graphics.hpp"
RenderWindow renderWindow;
Event eventSF;
GameWindow::GameWindow()
{
Initialize();
}
GameWindow::~GameWindow()
{
}
void GameWindow::Initialize()
{
// Set width & height to default settings
windowWidth = DEF_WIDTH;
windowHeight = DEF_HEIGHT;
// Create the render window
renderWindow.create(VideoMode(windowWidth, windowHeight), windowTitle, Style::Titlebar | Style::Close | Style::Resize);
Cmd::WriteLine("GameWindow Initialized!");
}
RenderWindow& GameWindow::GetRenderWindow()
{
return renderWindow;
}
void GameWindow::Run()
{
// Loop until window has closed
while (renderWindow.isOpen())
{
// Check current window events
CheckWindowEvent();
// Display window
DisplayWindow();
}
}
void GameWindow::DisplayWindow()
{
// Display the render window
renderWindow.clear();
renderWindow.display();
}
void GameWindow::CheckWindowEvent()
{
Event _event;
while (renderWindow.pollEvent(_event))
{
// Request for closing the window
if (_event.type == Event::Closed)
renderWindow.close();
}
}
and in my EntityManager.h I got :
#pragma once
#include "Entity.h"
#include "Player.h"
class EntityManager
{
public:
static EntityManager& Instance()
{
static EntityManager instance = EntityManager();
return instance;
}
private:
EntityManager();
~EntityManager();
void Initialize();
};
and my EntityManager.cpp
#include "StdAfx.h"
#include "EntityManager.h"
#include "GameWindow.h"
#include "Player.h"
EntityManager::EntityManager()
{
Initialize();
}
EntityManager::~EntityManager()
{
}
void EntityManager::Initialize()
{
Player::Create();
}
and now the Player.h
#pragma once
#include <SFML/Graphics.hpp>
#include "Entity.h"
using namespace sf;
class Player: Entity
{
public:
Player();
~Player();
void GotDamage(int damage);
static void Create();
void Draw();
void Shoot();
void Move(float x, float y);
void Controls(Event _eventSF);
private:
string name;
int health;
Event eventSF;
CircleShape playerVisual;
protected:
void Initialize() override;
};
and last the Player.cpp
#include "StdAfx.h"
#include "Player.h"
#include "GameWindow.h"
#include <SFML/Graphics.hpp>
Player::Player()
{
}
Player::~Player()
{
}
void Player::Create()
{
Player player;
player.Initialize();
player.Draw();
player.Controls(player.eventSF);
}
void Player::Initialize()
{
CircleShape playerVisual(50);
playerVisual.setPosition(800, 450);
playerVisual.setFillColor(sf::Color(100, 250, 50));
Entity::Initialize();
}
void Player::Controls(sf::Event _eventSF)
{
while(GameWindow::Instance().GetRenderWindow().isOpen())
{
while(GameWindow::Instance().GetRenderWindow().pollEvent(_eventSF))
{
switch(_eventSF.type)
{
case sf::Event::KeyPressed:
if (_eventSF.key.code == sf::Keyboard::Up)
{
Move(0,-1);
}
if (_eventSF.key.code == sf::Keyboard::Down)
{
Move(0,1);
}
if (_eventSF.key.code == sf::Keyboard::Left)
{
Move(-1,0);
}
if (_eventSF.key.code == sf::Keyboard::Right)
{
Move(1,0);
}
if (_eventSF.key.code == sf::Keyboard::BackSpace)
{
GotDamage(20);
}
break;
}
}
}
cout << " Checking Controls " << endl;
}
void Player::Move(float _x, float _y)
{
cout << "Move Player " << endl;
playerVisual.move(_x, _y);
Draw();
}
void Player::GotDamage(int _damage)
{
//for some reason health is -858993460
cout << "Your current health is " << Player::health << " you received " << _damage << " damage now you have " << Player::health - _damage << " health left. " << endl;
health -= _damage;
}
void Player::Draw()
{
cout << "Draw Player" << endl;
CircleShape visual(50);
playerVisual.setPosition(800, 450);
playerVisual.setFillColor(sf::Color(100, 250, 50));
GameWindow::Instance().GetRenderWindow().draw(visual);
}
I know it is a lot but I hope someone can help me.
To repeat my goal :
I am trying to get my player to be drawn on the screen and let him move sideways and if possible diagonal.
Thanks in advance!
To add onto KeyHeart's answer.
I hacked up your code a bit and managed to get it working.
Keep in mind the scope of your variables. There's CircleShape playerVisual(50) in Player::Initialize() which is a local variable, but you already have a CircleShape playerVisual inside Player.h! So the former is unnecessary. Likewise in Player::Create() you create a local player object.
I don't have a full copy of your code, so I assume what you plan on doing is having EntityManager handle all existing entities, such as the player. Therefore you should have Player player declared in the EntityManager's header file. Thus calling the constructor, which I have taken everything from Player::Create() and placed it into Player::Player(). And this player will exist for lifespan of EntityManager.
The order in which you should be updating the buffer is:
renderWindow.clear()
renderWindow.draw()
renderWindow.display()
As you have it now, you draw() then clear() effectively displaying nothing.
There are many approaches, but the simplest would be adding a call to Player::Draw() in GameWindow::DisplayWindow(). Though GameWindow will need a player object to call Draw().
Regarding moving the player. Player::Controls contains what may be an infinite loop in a sense. The line while (GameWindow::Instance().GetRenderWindow().isOpen()) will continue to loop as long as the window is open thus can block anything else from updating, such as drawing.
Shouldn't you be drawing playerVisual rather than visual which exists locally inside the Player::Draw() function?
Also shouldn't you call Player::Draw() in GameWindow::Run(), since you call GameWindow::DisplayWindow() which will update the screen. Calling Player::Draw() in Player::Move() limits drawing of the sprite only to when it moves. The results of this would be the sprite existing only in frames in which it moves otherwise an empty canvas.
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;
}
I am trying to make my first pong game in c++ with sfml but I have some problems
when I try to call the window.draw() function I think my code will explain the most.
This is my Game.h
#pragma once
#include <SFML/Graphics.hpp>
class Game
{
public:
Game();
void run();
private:
void processEvents();
void update();
void render();
sf::RenderWindow mWindow;
};
My game.cpp
#pragma once
#include "Game.h"
#include "Paddle.h"
Game::Game()
: mWindow(sf::VideoMode(640,480), "Pong")
{
}
void Game::run()
{
while (mWindow.isOpen())
{
processEvents();
update();
render();
}
}
void Game::processEvents()
{
sf::Event event;
while(mWindow.pollEvent(event))
{
if(event.type == sf::Event::Closed)
mWindow.close();
}
}
void Game::render()
{
mWindow.clear();
mWindow.draw(Paddle::player1);
mWindow.display();
}
void Game::update()
{
}
my Paddle.h and paddle.cpp
#pragma once
#include <SFML/Graphics.hpp>
class Paddle
{
public:
Paddle(int width, int height);
sf::RectangleShape player1(sf::Vector2f(int width,int height));
sf::RectangleShape player2(sf::Vector2f(int width,int height));
private:
};
My paddle.h
#include "Paddle.h"
Paddle::Paddle(int width,int height)
{
}
My main.cpp
#include "Game.h"
#include "Paddle.h"
int main()
{
Game game;
Paddle player1(10,60);
Paddle player2(10,60);
game.run();
}
That was all my code.
The problem is that I don't know how to draw the paddles in my Game.cpp
I think I should use some sort of pointers or reference-argument.
When I do it like this:
void Game::render()
{
mWindow.clear();
mWindow.draw(Paddle::player1);
mWindow.display();
}
I get an error. How do I solve this?
You need something like
class Game
{
public:
Game(Paddle & p1, Paddle & p2);
...
private:
...
Paddle & mP1;
Paddle & mP2;
};
Game::Game(Paddle & p1, Paddle & p2)
: mWindow(sf::VideoMode(640,480), "Pong"),
mP1(p1), mP2(p2)
{
}
void Game::render()
{
mWindow.clear();
mWindow.draw(mP1);
mWindow.display();
}
int main()
{
Paddle player1(10,60);
Paddle player2(10,60);
Game game(player1, player1);
game.run();
}