Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [Solved]Update function not working.  (Read 4140 times)

0 Members and 1 Guest are viewing this topic.

nickkorta

  • Newbie
  • *
  • Posts: 17
    • View Profile
[Solved]Update function not working.
« on: August 07, 2013, 09:44:21 pm »
I have a very simple game class that has a update and draw function that calls on other classes update and function classes.

Game.h
#include <SFML/graphics.hpp>
#include "Unit.h"

#pragma once
class Game
{
public:
        Game(void);
        ~Game(void);
private:
        void Update();
        void Draw();

        sf::RenderWindow window;
        Unit unit;
};
 

game.cpp

#include "Game.h"


Game::Game(void)
{
        window.create(sf::VideoMode(800,600),"Game");

        while (window.isOpen())
        {
                Update();
                Draw();
        }
}


Game::~Game(void)
{
}

void Game::Update()
{
        sf::Event event;
       
        while (window.pollEvent(event))
        {
                if (event.type == sf::Event::Closed || event.key.code == sf::Keyboard::Escape )
                        window.close();
        }
        unit.Update(event);
}

void Game::Draw()
{
        window.clear(sf::Color(116,146,208));
        unit.Draw(window);
        window.display();
}
 

The problem is that my Unit class update function is not working but If I move the "Unit unit" object under game.h to game.cpp everything works just fine.

#include "Game.h"

Unit unit;

Game::Game(void)
{
        window.create(sf::VideoMode(800,600),"Game");

        while (window.isOpen())
        {
                Update();
                Draw();
        }
}


Game::~Game(void)
{
}

void Game::Update()
{
        sf::Event event;
       
        while (window.pollEvent(event))
        {
                if (event.type == sf::Event::Closed || event.key.code == sf::Keyboard::Escape )
                        window.close();
        }
        unit.Update(event);
}

void Game::Draw()
{
        window.clear(sf::Color(116,146,208));
        unit.Draw(window);
        window.display();
}
This brings me to the question is should I make objects and variables under Game.h or Game.cpp. Am im missing something fundamental.

Thanks
« Last Edit: August 09, 2013, 10:35:58 pm by nickkorta »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10826
    • View Profile
    • development blog
    • Email
Re: Update function not working.
« Reply #1 on: August 07, 2013, 09:49:37 pm »
Not sure why you chose C# for highlighting...

Besides that you should make clear, what your problem is. "Doesn't work" will not help us in any way. What doesn't work and when doesn't it work? What are you trying to do? What do you expect to happen? What actually happens?
And if you talk about code that seems to make problems, but you show different code bits than the relevant ones, how should we know, what's going on in the other code? Always provide the relevant code. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

nickkorta

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Update function not working.
« Reply #2 on: August 07, 2013, 10:50:14 pm »
Sorry I used C# highlighting because I'm used to it, wasn't thinking clearly.

Under my Header file for Game(Game.h) I am declaring a new Unit class called unit.
Game.h
#include <SFML/graphics.hpp>
#include "Unit.h"

#pragma once
class Game
{
public:
        Game(void);
        ~Game(void);
private:
        void Update();
        void Draw();
        sf::RenderWindow window;
        Unit unit;
};

Under my Game.cpp I have to functions witch are Update and Draw that are called while the game is running.
The Update function is calling my Units Update function and the Draw function is calling the unit's draw function.
Game.cpp
#include "Game.h"

Game::Game(void)
{
        window.create(sf::VideoMode(800,600),"Game");

        while (window.isOpen())
        {
                Update();
                Draw();
        }
}


Game::~Game(void)
{
}

void Game::Update()
{
        unit.Update(event);
}

void Game::Draw()
{
        window.clear(sf::Color(116,146,208));
        unit.Draw(window);
        window.display();
}
 

What's suppose to happen is that my unit should appear on screen and animate but it appears on screen but does not animate ,but If I declare the Unit class inside game.cpp  instead of the header file then everything works.

Hope this is more clear, sorry.
« Last Edit: August 07, 2013, 10:51:47 pm by nickkorta »

The Hatchet

  • Full Member
  • ***
  • Posts: 135
    • View Profile
    • Email
Re: Update function not working.
« Reply #3 on: August 07, 2013, 10:57:08 pm »
Your 2nd post looks like you are trying to pass an 'event' to the unit even tho 'event' was never declared.  In your first post where you have a while(event) type loop you again are tryng to pass the event to the unit essentially after the event is already checked, used and flagged back to "all events done, exiting while() loop" so its just an empty event.

Maybe if you actually posted your unit.update() code we could actually see your problem.

nickkorta

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Update function not working.
« Reply #4 on: August 07, 2013, 11:09:51 pm »
Here is my proper Game.Cpp update function(Not sure what happened and I should have noticed it).
void Game::Update()
{
        sf::Event event;
       
        while (window.pollEvent(event))
        {
                if (event.type == sf::Event::Closed || event.key.code == sf::Keyboard::Escape )
                        window.close();
        }
        unit.Update(event);
}

Unit.cpp
#include "Unit.h"

Unit::Unit(void)
{
        fileName = "Content//Myrmidon.png";
        position.x = 0; position.y = 0;
        origin.x = 0;
        origin.y = 0;
        scale.x = 1;
        scale.y = 1;
        rotation = 0;

        animation2D.UpdateAnimationInfo(0,0,32,32,2,250,true);
}


Unit::~Unit(void)
{
}

void Unit::Update(sf::Event &_event)
{
        animation2D.Update();
}

void Unit::Draw(sf::RenderWindow &_window)
{
        spriteBatch.Draw(_window,fileName,position,animation2D.SourceRectangle(),origin,scale,rotation);
}

Here is my animation.cpp and spriteBatch.cpp code since you may need to look at that.
Aimation
#include "Animation2D.h"


Animation2D::Animation2D(void)
{
}

Animation2D::~Animation2D(void)
{
}

void Animation2D::Update()
{
        sourceRectangle.left = currentFrame * frameWidth;
        sourceRectangle.top = currentRow * frameHeight;
        sourceRectangle.width = frameWidth;
        sourceRectangle.height = frameHeight;

        if (animate)
        {
                time+=1;
                if (time >= interval)
                {
                        time = 0;
                        currentFrame++;
                        if (currentFrame > maxFrames)
                                currentFrame = 0;
                }
        }
        else
        {
                time = 0;
        }
}

void Animation2D::UpdateAnimationInfo(int _currentFrame, int _currentRow, int _frameWidth, int _frameHeight, int _maxFrames, float _interval, bool _animate)
{
        currentFrame = _currentFrame;
        currentRow = _currentRow;
        frameWidth = _frameWidth;
        frameHeight = _frameHeight;
        maxFrames = _maxFrames;
        interval = _interval;
        animate = _animate;
}

sf::IntRect Animation2D::SourceRectangle()
{
        return sourceRectangle;
}
 

SpriteBatch
#include "SpriteBatch.h"

SpriteBatch::SpriteBatch(void)
{
}


SpriteBatch::~SpriteBatch(void)
{
}

void SpriteBatch::Draw(sf::RenderWindow &_window ,std::string _fileName, sf::Vector2f _position,sf::IntRect _sourceRect,sf::Vector2f _origin, sf::Vector2f _scale, float _rotation)
{
        texture.loadFromFile(_fileName);
        sprite.setTexture(texture);
        sprite.setPosition(_position.x,_position.y);
        sprite.setTextureRect(_sourceRect);
        sprite.setOrigin(_origin.x,_origin.y);
        sprite.setScale(_scale.x,_scale.y);
        sprite.setRotation(_rotation);
        _window.draw(sprite);
}
 

Thanks for putting up with my stupidity.
 

Gobbles

  • Full Member
  • ***
  • Posts: 132
    • View Profile
    • Email
Re: Update function not working.
« Reply #5 on: August 08, 2013, 12:19:46 am »
void SpriteBatch::Draw(sf::RenderWindow &_window ,std::string _fileName, sf::Vector2f _position,sf::IntRect _sourceRect,sf::Vector2f _origin, sf::Vector2f _scale, float _rotation)
{
    texture.loadFromFile(_fileName);
    sprite.setTexture(texture);
...
 

your loading the texture and setting it into a sprite every single draw call? this only needs to be done once.
While not the answer your looking for, thought I'd point it out.

And as The Hatchet mentioned, by the time unit.Update(event); is hit, the events have all been handled. Move that line up so you end up with this:

void Game::Update()
{
    sf::Event event;
   
    while (window.pollEvent(event))
    {
        if (event.type == sf::Event::Closed || event.key.code == sf::Keyboard::Escape )
            window.close();
        unit.Update(event);
    }
}
 

nickkorta

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Update function not working.
« Reply #6 on: August 08, 2013, 01:26:06 am »
I moved the Unit.Update(event) method into the while loop. Still the same as before. As I said in my first and second post is if I move  "Unit unit" from Game.h to Game.cpp everything works. Why is that?

The Hatchet

  • Full Member
  • ***
  • Posts: 135
    • View Profile
    • Email
Re: Update function not working.
« Reply #7 on: August 08, 2013, 03:33:32 am »
What happens if you remove the #pragma once from your Game.h?   Other than that I have no clue, everything looks ok, if it was out of scope for any reason the compiler would yell.  The only reason(and probably not even a good reason) I could think your Unit unit doesn't get seen when in the header is from the #pragma once if say...your main.cpp or whatever calls #include "Game.h" and the compiler compiles that first before hitting the Game.cpp source file, it will see that Game.h had already been included once and would essentially not get included in the game.cpp compilation.   But i'm pretty sure i'm wrong since I would think if such a thing could happen it would throw compiler errors.

Also, you should throw some std::cout lines in your update method, see if the program thread is even getting into it.  If it compiles right but just doesn't seem to be doing anything the thread may be getting in there and the answer may show itself.  Printing to the console can be one of the most basic and easiest to implement debugging tools and I don't understand why people don't think to do it more often.
« Last Edit: August 08, 2013, 03:45:04 am by The Hatchet »

nickkorta

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Update function not working.
« Reply #8 on: August 08, 2013, 05:18:31 am »
I got rid of #pragma once in my Game.h and nothing happened. I also used std::cout and all the functions are being hit. I tested this in Unit Update and Draw, draw in spritebatch, and update in animatin2D. I also put break points and looked at what happening different and I found nothing.  With this said I am really Lost. Is it wrong practice to declare classes inside of .cpp files instead of the header files. I never had to worry about this in C# so code structuring your code correctly in C++ is new to me.

Thanks

Barlog

  • Guest
Re: Update function not working.
« Reply #9 on: August 08, 2013, 07:43:50 am »
Nickkorta, you should not handle events like that

if (event.type == sf::Event::Closed || event.key.code == sf::Keyboard::Escape )

As from tutorial about events http://www.sfml-dev.org/tutorials/2.1/window-events.php
Quote
sf::Event is a union, which means that only one of its member is valid at a time (remember your C++ lesson: all the members of a union share the same memory space). The valid member is the one that matches the event type, for example event.key for a KeyPressed event. Trying to read any other member will result in an undefined behaviour (most likely: random or invalid values). So never try to use an event member that doesn't match its type.

As for your problem. Try to add your animation and spritebatch code to the test files in attachment (which is based on your game.* and unit.* files) and see if problem persists.
I've included only *.cpp and *.hpp files because I do not know in which OS and IDE you are developing.

nickkorta

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Update function not working.
« Reply #10 on: August 08, 2013, 06:20:15 pm »
Ya the problem persists. I'm using Windows 8 and Visual studio 2012. Your animation with the shape was working when Unit unit was in the header file or the cpp file. Mine only works when Unit unit is declared in the cpp file.
Thanks for the help so far.

The Hatchet

  • Full Member
  • ***
  • Posts: 135
    • View Profile
    • Email
Re: Update function not working.
« Reply #11 on: August 08, 2013, 09:15:51 pm »
You say its hitting the update function in your game, unit, animation2d and spritebatch.  Is it getting into all the control statements in your animation2d class?  If the updates are hitting your std::couts then it technically is working, but that just means the problem is further in or maybe something is initialized correctly.

  I'm not seeing anywhere in the code you've given if the 'time' variable gets initually set.  If you don't initially set this to 0 you can't assume that by just declaring it it will be 0.   If you don't set it to 0 to start with it could initialize as say -352784 and since you never test for a negative number your if (time >= interval) may never fire.  Put a std::cout in each control statement and print out any variable that should be changing:  time, currentframe, currentrow, etc.

Also if the project isn't too big maybe upload a copy of the code that compiles but doesn't work and I could take a look at it.
« Last Edit: August 08, 2013, 09:33:03 pm by The Hatchet »

nickkorta

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Update function not working.
« Reply #12 on: August 09, 2013, 03:32:25 am »
[Answer]
setting Time to 0 did the trick. I still don't understand that it worked when the Unit object was declared in the .cpp file and not the header file.

Thanks
« Last Edit: August 09, 2013, 10:35:27 pm by nickkorta »

The Hatchet

  • Full Member
  • ***
  • Posts: 135
    • View Profile
    • Email
Re: Update function not working.
« Reply #13 on: August 09, 2013, 07:48:36 am »
Pure luck.  Depending when and where a variable gets initilized can change what random piece of memory gets used.  or maybe one uses the stack while the other uses the heap.  I don't know but figured that was still it after reading through all the code you posted.

nickkorta

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Update function not working.
« Reply #14 on: August 09, 2013, 10:34:51 pm »
Makes sense. Thanks again. I should have caught that.