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

Author Topic: Sending variables to the screen  (Read 3282 times)

0 Members and 1 Guest are viewing this topic.

wvtrammell

  • Jr. Member
  • **
  • Posts: 70
    • View Profile
Sending variables to the screen
« on: March 31, 2011, 12:09:17 am »
I am new at this so I put together a few lines of code to place digits (0 - 9) to the screen sequentially.  However it did not come out that way.  The program cycles continously but only writes to the screen when a key is pressed.  Would some one point out my error in the code please? Thanks
Warren Trammell


Code: [Select]
#include <SFML/Graphics.hpp>
#include <iostream>
#include <sstream>

int main()
{
int x = 0, y = 0, count = -1;
char buffer[10];

    // Create main window
    sf::RenderWindow App(sf::VideoMode(1600, 900), "SFML Fonts");

  // Clear screen
App.Clear(sf::Color(128,128,128));

    // Load a font from a file
    sf::Font MyFont;
    if (!MyFont.LoadFromFile("/users/warren/projects/impact.ttf", 50))
        return EXIT_FAILURE;

    // Start game loop
    while (App.IsOpened())
    {
count++;
if(count > 9) count = 0;

    // Process events
        sf::Event Event;
        while (App.GetEvent(Event))
        {
             x = x + 50;
if(x > 1500)
{
x = 0;
y = y + 50;
}

// Create a graphical string
sf::String Text;
sprintf(buffer,"%i",count);
Text.SetText(buffer);
Text.SetFont(MyFont);
Text.SetColor(sf::Color::Black);
Text.SetPosition(x, y);
Text.SetSize(50);

// Draw our strings
App.Draw(Text);

// Finally, display rendered frame on screen
App.Display();
           
  // Close window : exit
            if (Event.Type == sf::Event::Closed)
                App.Close();

        }
}

    return EXIT_SUCCESS;
}

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Sending variables to the screen
« Reply #1 on: March 31, 2011, 01:29:57 am »
1. The Draw(), Clear() and Display() calls are inside your event handler's while loop.
2. Your ordering is wrong: At first call Clear(), then Draw() your stuff and then Display().
3. Please enclose source code in BBCode's 'code' tags next time. :)

wvtrammell

  • Jr. Member
  • **
  • Posts: 70
    • View Profile
Order
« Reply #2 on: March 31, 2011, 05:37:01 pm »
Thanks
Are you saying the code should be inside an if statement when inside the event loop?
Warreni

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Sending variables to the screen
« Reply #3 on: March 31, 2011, 06:58:57 pm »
I don't think so. Read carefully the tutorial and have a look at this code sample http://www.sfml-dev.org/documentation/1.6/.
SFML / OS X developer

OniLinkPlus

  • Hero Member
  • *****
  • Posts: 500
    • View Profile
Sending variables to the screen
« Reply #4 on: April 01, 2011, 04:06:43 am »
The only thing that should be inside the event loop is the event handling. Remove the rendering, display, clear, etc code from the event loop.
I use the latest build of SFML2

Gibgezr

  • Newbie
  • *
  • Posts: 33
    • View Profile
Sending variables to the screen
« Reply #5 on: April 01, 2011, 03:16:03 pm »
Here is an example of a simple skeleton code architecture to base a game on, pay special attention to the Game::Run() and Game::Logic() member functions:

Code: [Select]

#include "Game.h"

Game::Game(void)
{
App=NULL;
// Create the main rendering window
App = new sf::RenderWindow(sf::VideoMode(800, 640, 32), "TileMap Example");

//hide the mouse cursor in the window
App->ShowMouseCursor(false);

GameState = STARTUP;

stateTime = 0;//not used in the current code, but included for time-based state changes later,
                //like displaying a graphic for a few seconds

the_map = new Map(App);
}

Game::~Game(void)
{
delete the_map;

delete App;
}

void Game::Run(void)
{
while (App->IsOpened())
    {
        // Process events        
        while (App->GetEvent(Event))
        {
            // Close window : exit
            if (Event.Type == sf::Event::Closed)
{
                App->Close();
return;
}
        }
       
//perform our game logic
//App->Clear(sf::Color(0, 0, 0));
Logic(App->GetFrameTime());

// Display window contents on screen
App->Display();
    }
}

void Game::DrawLevel(void)
{
the_map->DrawMap();
}

void Game::DoPhysics(float time_passed)
{

}

void Game::Logic(float time_passed)
{
switch(GameState)
{
case LOAD1:
{
the_map->LoadMap("data/Level1.txt");
GameState = PLAY1;
}
break;

case PLAY1:
{
//perform the game's physics calculations
DoPhysics(time_passed);

DrawLevel();
}
break;

case STARTUP:
{
the_map->SetScreen(0, 0, 10, 8);
GameState = LOAD1;
}
break;
default:
break;
}//end switch
}

Gibgezr

  • Newbie
  • *
  • Posts: 33
    • View Profile
Sending variables to the screen
« Reply #6 on: April 01, 2011, 03:35:20 pm »
Here is how I am currently handling a lot of my input; this is a simple example, not perfect code by any means:

Code: [Select]

void Game::DoInput(void)
{
if(App->GetInput().IsKeyDown(sf::Key::Left)) turn_left = true;
else turn_left = false;

if(App->GetInput().IsKeyDown(sf::Key::Right)) turn_right = true;
else turn_right = false;

if(App->GetInput().IsKeyDown(sf::Key::Up)) thrust = true;
else thrust = false;

if(App->GetInput().IsKeyDown(sf::Key::Space)) fire = true;
else fire = false;
}

void Game::DoPhysics(float time_passed)
{
if(turn_left) theShip.angle += TURN_SPEED * time_passed;
if(turn_right) theShip.angle -= TURN_SPEED * time_passed;

if(fire) theShip.Shoot();

if(thrust) theShip.Thrust(time_passed);

theShip.Update(time_passed);
theAsteroid.Update(time_passed);

//slow down the ship a bit
for(int partialseconds_passed = time_passed * 10000.f;partialseconds_passed >= 0; --partialseconds_passed)
theShip.motion *= 0.99999;

//collision detection
if(theShip.CheckShotCollision(&theAsteroid))
{
//reset the asteroid
float rand_angle = rand()%360;
rand_angle /= 57.2957795f; //convert from degrees to radians
theAsteroid.motion.x = -sin(rand_angle);
theAsteroid.motion.y = -cos(rand_angle);
theAsteroid.motion *= ASTEROID_SPEED;
theAsteroid.pos.x = 30;
theAsteroid.pos.y = 30;
}

}

void Game::DrawLevel(void)
{
App->Clear();

theShipSprite->SetRotation(theShip.angle * 57.2957795f);
theShipSprite->SetPosition(theShip.pos.x, theShip.pos.y);
App->Draw(*theShipSprite);

theAsteroidSprite->SetPosition(theAsteroid.pos.x, theAsteroid.pos.y);
App->Draw(*theAsteroidSprite);

for(int i = 0; i < theShip.shots.size(); ++i)
{
theShotsSprite->SetPosition(theShip.shots[i]->pos.x, theShip.shots[i]->pos.y);
App->Draw(*theShotsSprite);
}
}


The Game::Run() function DOES NOT CHANGE from the one I posted before; nothing is added to it's event handling loop. If I was tracking mouse movement, I would probably add that into the event loop of Game::Run(), just because it's simple.

So, with the code above, my Game::Logic playstate looks like:
Code: [Select]

case PLAY1:
{
DoInput();
DoPhysics(time_passed);
DrawLevel();
}
break;


By doing things this way, I can easily have totally different DoInput() functions for different game states, like DoInputPlay2() etc., if they are required. Also, I have followed the cardinal rule of application/game programming by following the CONTROL/MODEL/VIEW paradigm, and seperating my CONTROL (inputs) from my MODEL (physics and rules) from my VIEW (rendering). That's why the DoInput() function only sets flag variables but doesn't act on them, and the DoPhysics() function doesn't know anything about any input events, it just acts on these flag variables that allow the CONTROLLER to communicate to the MODEL "what the player wishes to do". Keeping the three parts of the program compartmentalized like this is very important for large projects, in my experience.

Looking at the above (quickly-written) code, I would improve it by making a Ship::Turn() function, among other things. Anyway, I hope this is helpful.

 

anything