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"
Related
I'm trying to create a game. I have a class GameObjects that many classes will inherit from. The class GameObject has a draw method that takes the window address to the display. Why does the sprite show up without the texture when displayed like this?
This is the texture, more of a placeholder. I was able to load it in other files directly creating the sprite and drawing it.
Here is my main.cpp
#include <iostream>
#include "Game.h"
int main()
{
//window setup
Game game;
//Initialize game
game.start();
return 0;
}
Here is my Game.h
#pragma once
#include "GameObject.h"
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/Audio.hpp>
#include <iostream>
class Game
{
private:
//window variables
int w_width;
int w_height;
sf::RenderWindow window;
sf::Event ev;
bool isRunning;
std::vector<GameObject> o_vector;
void initVariables();
void initWindow();
void initObjects();
void drawObjects();
public:
void start();
void run();
void input();
void update();
void render();
};
And Game.cpp
#include "Game.h"
#include "GameObject.h"
void Game::start()
{
this->initVariables();
this->initWindow();
this->initObjects();
this->run();
}
//Initializations
void Game::initVariables()
{
isRunning = true;
//window variables
w_width = 1280;
w_height = 720;
}
void Game::drawObjects()
{
for (int o_count = 0; o_count < o_vector.size(); o_count++)
{
o_vector.at(o_count).draw(window);
}
}
void Game::initWindow()
{
//window creation
window.create(sf::VideoMode(w_width, w_height), "The Dungeon Crawler", sf::Style::Titlebar | sf::Style::Close | sf::Style::Resize);
}
void Game::initObjects()
{
GameObject baseObject;
o_vector.push_back(baseObject);
}
void Game::run()
{
while (isRunning)
{
input();
update();
render();
}
}
void Game::input()
{
while (window.pollEvent(ev))
{
switch (ev.type)
{
case sf::Event::Closed:
window.close();
break;
case sf::Event::KeyPressed:
switch (ev.key.code)
{
case sf::Keyboard::Escape:
window.close();
break;
case sf::Keyboard::A:
break;
}
}
}
}
void Game::update()
{
}
void Game::render()
{
window.clear(sf::Color(0, 0, 128));
drawObjects();
window.display();
}
Here is GameObject.h
#pragma once
#include <vector>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
class GameObject
{
private:
std::string name;
std::vector<int> o_position;
std::vector<int> o_size;
std::string t_path;
sf::Sprite o_sprite;
sf::Texture o_texture;
void initVariables();
public:
//Constructors & Destructors
GameObject();
~GameObject();
//Getters
std::vector<int> getPos();
std::vector<int> getSize();
sf::Sprite getSprite();
//Setters
void setPos(std::vector<int>pos_in);
void setSize(std::vector<int> size_in);
//Graphics
void draw(sf::RenderWindow &displayWindow);
};
And GameObject.cpp
#include "GameObject.h"
GameObject::GameObject()
{
initVariables();
}
GameObject::~GameObject()
{
}
void GameObject::initVariables()
{
o_position = { 0,0 };
o_size = { 64,64 };
t_path = "Resources/EmptySquare.png";
if (!o_texture.loadFromFile(t_path))
{
std::cout << "Failed to load" << std::endl;
return;
}
o_sprite.setTexture(o_texture);
}
std::vector<int> GameObject::getPos()
{
return o_position;
}
std::vector<int> GameObject::getSize()
{
return o_size;
}
sf::Sprite GameObject::getSprite()
{
return o_sprite;
}
void GameObject::setPos(std::vector<int> pos_in)
{
o_position = pos_in;
}
void GameObject::setSize(std::vector<int> size_in)
{
o_size = size_in;
}
void GameObject::draw(sf::RenderWindow &displayWindow)
{
displayWindow.draw(o_sprite);
}
Thank you for any help!
the problem is this line in Game::initObjects()
GameObject baseObject;
o_vector.push_back(baseObject);
you creata a copy of GameObject.
so it will make a copy of o_sprite.
the o_sprite copies the texture pointer.
after this function ends, the texture pointer is no longer valid.
sf::Sprite has the member const Texture* m_texture; and when calling sf::Sprite::setTexture(const Texture& texture) this member m_texture will in fact point to the texture. That texture will be destructed after initObjects() ends, and your element at position 0 will have a o_sprite.m_texture that points to this destructed object. SFML/Sprite.hpp
you could define the correct operator=(GameObject) that implements the correct sprite copy - or in this case simply say:
void Game::initObjects()
{
o_vector.resize(1);
}
resize will call the constructor of GameObject and you will have no copies and therefore dangling pointers.
Another way would be for you to allocate game object on the heap and store a pointer to it in the vector. This way you will avoid the cost of copying.
To make these changes, declare baseObject as private member of Game class and in initObjects method allocate it on the heap.
class Game
{
private:
GameObject *baseObject;
std::vector<GameObject *> o_vector;
};
void Game::initObjects()
{
baseObject = new GameObject;
o_vector.push_back(baseObject);
}
void Game::drawObjects()
{
for (int o_count = 0; o_count < o_vector.size(); o_count++)
{
o_vector.at(o_count)->draw(window); // use -> operator to call draw
}
}
PS: Instead of raw pointer, you can also use C++11 smart pointer.
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.
New to C++, I'm trying to make "platforms" spawn every 2 seconds and go upwards. However, the platform disappears when a new Platform is pushed onto the platforms vector.
Platform.h:
#pragma once
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <vector>
class Platform
{
private:
sf::RectangleShape shape;
public:
Platform() = default;
Platform(const Platform& platform);
void updatePos();
sf::RectangleShape getShape() { return shape; }
};
Platform.cpp:
#include "Platform.h"
Platform::Platform(const Platform& platform)
{
shape.setSize(sf::Vector2f(300.f, 40.f));
shape.setPosition(1920.f / 2.f - shape.getSize().x / 2.f, 1080.f);
}
void Platform::updatePos()
{
shape.move(sf::Vector2f(0.f, -5.f));
}
Game.h:
#pragma once
#include "Platform.h"
#include <iostream>
class Game
{
private:
sf::RenderWindow window{ sf::VideoMode(1920, 1080), "Dodge the Spikes", sf::Style::Fullscreen };
std::vector<Platform> platforms;
bool gameOver{};
unsigned int platformTimer{};
public:
Game() = default;
void update();
void draw();
void run();
};
Game.cpp:
#include "Game.h"
void Game::update()
{
if (!gameOver)
{
//spawn platforms
platformTimer++;
if (platformTimer >= 120)
{
platforms.push_back(Platform{});
platformTimer = 0;
}
//update platforms
for (auto i{platforms.begin()}; i < platforms.end();)
{
i->updatePos();
i++;
}
}
}
void Game::draw()
{
for (auto i{ platforms.begin() }; i < platforms.end();)
{
window.draw(i->getShape());
i++;
}
}
void Game::run()
{
while (window.isOpen())
{
sf::Event evnt;
while (window.pollEvent(evnt))
{
if (evnt.type == sf::Event::Closed)
{
window.close();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
{
window.close();
}
}
this->update();
window.clear();
this->draw();
window.display();
}
}
Main.cpp
#include <iostream>
#include "MainGame.h"
int main(int argc,char* argv[])
{
MainGame maingame;
maingame.run();
return 0;
}
MainGame.h
#pragma once
#include <SDL2/SDL.h>
#include <GL/glew.h>
enum class GameState
{
PLAY,EXIT
};
class MainGame
{
public:
MainGame();
~MainGame();
void run();
private:
void initsystem();
void gameLoop();
void processInput();
void drawGame();
SDL_Window* _window;
int _screenWidth;
int _screenHeight;
GameState _gameState;
};
MainGame.cpp
#include "MainGame.h"
#include <iostream>
#include <string>
void fatalError(std::string errorString)
{
std::cout<<errorString<<std::endl;
std::cout<<"Enter any key"<<std::endl;
int tmp;
std::cin>>tmp;
SDL_Quit();
}
MainGame::MainGame()
{
_window=nullptr;
_screenWidth=640;
_screenHeight=480;
_gameState=GameState::PLAY;
}
MainGame::~MainGame()
{
}
void MainGame::run()
{
initsystem();
gameLoop();
}
void MainGame::initsystem()
{
//initialize SDL
SDL_Init(SDL_INIT_EVERYTHING);
_window=SDL_CreateWindow("Game",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,_screenWidth,_screenHeight,SDL_WINDOW_OPENGL);
if(_window==nullptr)
{
fatalError("Sdl window failed to load");
}
SDL_GLContext glContex=SDL_GL_CreateContext(_window);
if(glContex==nullptr)
{
fatalError("SDL_Glcontex failed to load");
}
GLenum error =glewInit();
if(error !=GLEW_OK)
{
fatalError("could no initialize Glew!");
}
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
glClearColor(0.0f,0.0f,1.0f,1.0f);
}
void MainGame::gameLoop()
{
while(_gameState!=GameState::EXIT)
{
processInput();
}
}
void MainGame::processInput()
{
SDL_Event evnt;
while(SDL_PollEvent(&evnt))
{
switch(evnt.type)
{
case SDL_QUIT:
_gameState=GameState::EXIT;
break;
case SDL_MOUSEMOTION:
std::cout<<evnt.motion.x<<" "<<evnt.motion.y<<std::endl;
}
}
}
void MainGame::drawGame()
{
glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableClientState(GL_COLOR_ARRAY);
glBegin(GL_TRIANGLES);
glColor3f(1.0f,0.0f,0.0f);
glVertex2f(0,0);
glVertex2f(0,500);
glVertex2f(500,0);
glEnd();
SDL_GL_SwapWindow(_window);
}
so i was following an OpenGL tutorial and everything was alright until colors got involved and the one i am following is using a window PC and i am using Debian and the code compiles just fine but i am not getting anything in the output.[![ that's the output !!
i mean i should a blue screen and a triangle.
and i am using there linker in code::block -lSDL2 -lglut -lGLEW -lGLU -lm -lGL
i don't know if i am missing some imp linker or something is wrong with the code itself.
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();
}