SFML community forums
Help => General => Topic started by: metulburr on August 28, 2011, 11:51:32 pm
-
i am ok at running the console apps and can figure out why things are there and what they are for, but using SFML i cant seem to follow what is going on(therefore unable to use it without copying and pasting peoples responses for my program)
1) At what point should i depart from console programs (becuz they are kind of boring), i can make small (very small) text games, somewhat know how to use classes, loops, etc.
2) SFML seems to have trouble explaining things well when going from console to SFML.
3) i read through the tutorials on this site, and they are not very (console to SFML) friendly. I have to keep posting questions on Cplusplus forums due to most answers on the beginners forum are regarding console apps.
4) is there a tutorial for beginners starting SFML directly from console learning??? if so please reply
5) what exactly can u use SFML for? 2D games, GUI programs(i guess meaning like a windows app) ( like menu selection for the game?). if you wanted to make 3D games, why could you not use SFML and just use their libraries for menus and make your own classes for the 3D?
Thanks in Advance,
metulburr
-
one example is this code. i tried putting a simple png image to turn with WASD movements, and i wanted it to turn the direction that the user chose (but only once). my original image is suppose to be a top-down view of a guy(thus the reason for turning) but the ship game me a point to see where its heading is easier.
1)line 37, i tried putting an if() to only allow it to do it only once based on its direction
#include <SFML/Graphics.hpp>
int main()
{
// Create the main rendering window
sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Pac-Man");
// Load the sprite image from a file
sf::Image Image;
if (!Image.LoadFromFile("ship.png"))
return EXIT_FAILURE;
// Create the sprite
sf::Sprite ship(Image);
// Change its properties
ship.SetColor(sf::Color(0, 255, 255, 128));
ship.SetPosition(200.f, 100.f);
ship.SetScale(0.f, 0.f);
ship.Rotate(0.f);
// Start game loop
while (window.IsOpened())
{
// Process events
sf::Event Event;
while (window.GetEvent(Event))
{
// Close window : exit
if (Event.Type == sf::Event::Closed)
window.Close();
if(Event.Type == sf::Event::KeyPressed)
{
if(!(ship.Rotate(270.f)))
{
switch(Event.Key.Code)
{
case sf::Key::A:
ship.Rotate(270.f);
break;
}
}
}
if(Event.Type == sf::Event::KeyPressed)
{
switch(Event.Key.Code)
{
case sf::Key::W:
ship.Rotate(0.f);
break;
}
}
if(Event.Type == sf::Event::KeyPressed)
{
switch(Event.Key.Code)
{
case sf::Key::D:
ship.Rotate(90.f);
break;
}
}
if(Event.Type == sf::Event::KeyPressed)
{
switch(Event.Key.Code)
{
case sf::Key::S:
ship.Rotate(180.f);
break;
}
}
}
// Get elapsed time
float ElapsedTime = window.GetFrameTime();
// Move the sprite
if (window.GetInput().IsKeyDown(sf::Key::A))
{
ship.Move(-200 * ElapsedTime, 0);
}
if (window.GetInput().IsKeyDown(sf::Key::D)) ship.Move( 200 * ElapsedTime, 0);
if (window.GetInput().IsKeyDown(sf::Key::W)) ship.Move(0, -200 * ElapsedTime);
if (window.GetInput().IsKeyDown(sf::Key::S)) ship.Move(0, 200 * ElapsedTime);
// Rotate the sprite
if (window.GetInput().IsKeyDown(sf::Key::Add)) ship.Rotate(- 200 * ElapsedTime);
if (window.GetInput().IsKeyDown(sf::Key::Subtract)) ship.Rotate(+ 200 * ElapsedTime);
// Clear screen
window.Clear();
// Display sprite in our window
window.Draw(ship);
// Display window contents on screen
window.Display();
}
return EXIT_SUCCESS;
}
EDIT 1: i posted this code thinking this forum had number lines for codes line 37 is if(!(ship.Rotate(270.f)))...i already know that this is invalid
-
1) At what point should i depart from console programs (becuz they are kind of boring), i can make small (very small) text games, somewhat know how to use classes, loops, etc.
When you can code freely without copy pasting code/modifying code. And when you understand classes very well with inheretance and public/private instancing.(when you understand object orientated programming)
2) SFML seems to have trouble explaining things well when going from console to SFML.
the 1.6 tutorial explains you very well how to set up SFML with your developer enviroment
3) i read through the tutorials on this site, and they are not very (console to SFML) friendly. I have to keep posting questions on Cplusplus forums due to most answers on the beginners forum are regarding console apps.
4) is there a tutorial for beginners starting SFML directly from console learning??? if so please reply
The tutorials are already easy enough.
5) what exactly can u use SFML for? 2D games, GUI programs(i guess meaning like a windows app) ( like menu selection for the game?). if you wanted to make 3D games, why could you not use SFML and just use their libraries for menus and make your own classes for the 3D?
http://sfml-dev.org/features.php
And you have no idea what you are talking about.
-
Your logic is heavily flawed. Give me a minute and I'll redo your code to be a bit cleaner/more legible.
-
@Atomical
of course i know what i am talking about...i am talking about myself not understanding the tutorials of this SFML site. besides that is the purpose of forums, is to get numerous explanations from different people (becuz people learn different ways)
Numerous C++ books explain in different ways...it took me at least 5 books just to learn console programming, but there seems to be only one tutorial for SFML. Different people word things that is understanding to some, but confusing to others. This tutorial just seems confusing the way its written.
-
@Serapth
thank you very much, maybe i could make sense of (why things are there) with your rewritten code
-
@Serapth
thank you very much, maybe i could make sense of (why things are there) with your rewritten code
Here you go, for the record its a quick hack job. The nested switches get a little messy and should be reorganized eventually.
Also, there is no bounds checking to the corner of the screen ( when you hit the screens edge, it will probably crash ) and rotation is from the top left of the sprite instead of the center, but fixing both of these issues would have just complicated things, both things should be easy enough for you to fix later.
// SFMLTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
int main(int argc, char ** argv)
{
sf::RenderWindow window;
window.Create(sf::VideoMode(1024,768,32),"Test");
sf::Image img;
if(!img.LoadFromFile("ship.png")) return 42;
sf::Sprite sprite(img);
sprite.SetX(( 1024/2 - img.GetWidth() /2));
sprite.SetY((768/2 - img.GetHeight() /2));
//Gameloop
bool done = false;
while(!done)
{
sf::Event myEvent;
while(window.GetEvent(myEvent))
{
switch(myEvent.Type)
{
case sf::Event::Closed:
done = true;
break;
case sf::Event::KeyPressed:
{
switch(myEvent.Key.Code)
{
case sf::Key::W:
{
sprite.Move(0,-1);
break;
}
case sf::Key::A:
{
sprite.Move(-1,0);
break;
}
case sf::Key::S:
{
sprite.Move(0,1);
break;
}
case sf::Key::D:
{
sprite.Move(1,0);
break;
}
case sf::Key::Q:
{
sprite.Rotate(-1.f);
break;
}
case sf::Key::E:
{
sprite.Rotate(1.f);
break;
}
}
break;
}
}
}
// done handling events
window.Clear(sf::Color::White);
window.Draw(sprite);
window.Display();
}
return 0;
}
-
Hmmm, perhaps comments might help more. Same code commented:
// SFMLTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
int main(int argc, char ** argv)
{
sf::RenderWindow window; // Declare a window object
window.Create(sf::VideoMode(1024,768,32),"Test"); // Create the window, setting the resolution and pixel depth
sf::Image img; // Declare an image object
if(!img.LoadFromFile("ship.png")) return 42; // Load our image from file, if it fails, exit the program
sf::Sprite sprite(img); // Declare a sprite, and in it's constructor assign an image to it. There can be multiple sprites to a single image
sprite.SetX(( 1024/2 - img.GetWidth() /2)); // Position the sprite in the middle of the screen
sprite.SetY((768/2 - img.GetHeight() /2));
//Gameloop
bool done = false; // Boolean variable flag that will tell us when to exit the program
while(!done) // Loop ( "game loop" ) forever, or until the "done" flag is set to true
{
sf::Event myEvent; // declare an event
while(window.GetEvent(myEvent)) // GetEvent returns true if there is a new event, if there is an event, handle it, otherwise proceed to drawing
{
switch(myEvent.Type) // Switch ( think a branching if statement ) on the type of event we are processing
{
case sf::Event::Closed: // If the event is a close type, set the done flag to true so we exit next pass through the loop
done = true;
break; // You need a break statement for every case: condition, or the switch will "fall through" and continue processing
case sf::Event::KeyPressed: // Is it a key press event?
{
switch(myEvent.Key.Code) // If so, which Key?
{
case sf::Key::W: // Handle the various keys
{
sprite.Move(0,-1); // Move up 1 pixel
break;
}
case sf::Key::A:
{
sprite.Move(-1,0); // Move left
break;
}
case sf::Key::S:
{
sprite.Move(0,1); // Move down
break;
}
case sf::Key::D:
{
sprite.Move(1,0); // Move right
break;
}
case sf::Key::Q:
{
sprite.Rotate(-1.f); // Rotate 1 degree left
break;
}
case sf::Key::E:
{
sprite.Rotate(1.f); // Rotate 1 degree right
break;
}
}
break;
}
}
}
// done handling events
window.Clear(sf::Color::White); // Clear the screen to white
window.Draw(sprite); // Draw your sprite to the screen
window.Display(); // Display the screen
}// Now we are done "one" pass through the game loop, continue to next pass getting input, drawing screen, etc... until done is true
window.Close(); // Close the window
return 0; // Return "everythingAOK code
}
-
It's possible to have more than one event between two game loops, so I think
while(window.GetEvent(myEvent))
is better than
if(window.GetEvent(myEvent))
-
Your logic is heavily flawed, in a game loop you should only poll for a single event. Give me a minute and I'll redo your code to be a bit cleaner/more legible.
Except that is an EXTREMELY dumb idea (poll for a single event). You are supposed to do a while loop for event handling. If you don't, then it can cause your program to lag due to too many events being stockpiled. In fact, on certain operating systems (certain versions of Windows come to mind), you MUST poll as many events as possible per frame, or the program slows to a crawl.
-
Your logic is heavily flawed, in a game loop you should only poll for a single event. Give me a minute and I'll redo your code to be a bit cleaner/more legible.
Except that is an EXTREMELY dumb idea (poll for a single event). You are supposed to do a while loop for event handling. If you don't, then it can cause your program to lag due to too many events being stockpiled. In fact, on certain operating systems (certain versions of Windows come to mind), you MUST poll as many events as possible per frame, or the program slows to a crawl.
Very well, I was going off something I thought I had read recently in the documentation that SFML worked at an event per loop, but either way, it's really not a big deal.
As Lo-X already wrote, simply change the if to a while and the event stack will empty itself. Edited example to use while instead of if.
As to what I said regarding his initial code, I was actually very poor in my wording anyways. It was not the handling more than one event that was flawed, it was handling events in more than one place and polling events multiple times per pass that was flawed and I addressed in my example.
-
so whats wrong with this code? it does the same?
i was initially asking though that the front of the "image" always maintain 'W'
so if the user held S the ship goes down, the ship turns downwards, and if the user held D the ship turned right and moved right? all the times i tried the ship moves in the direction that i wanted but doesnt stop turning?
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Test");
sf::Image Image;
if (!Image.LoadFromFile("ship.png"))
return EXIT_FAILURE;
sf::Sprite ship(Image);
ship.SetColor(sf::Color(0, 255, 255, 128));
ship.SetPosition(200.f, 100.f);
ship.SetScale(0.f, 0.f);
ship.Rotate(0.f);
// Start game loop
while (window.IsOpened())
{
// Process events
sf::Event Event;
while (window.GetEvent(Event))
{
// Close window : exit
if (Event.Type == sf::Event::Closed)
window.Close();
if(Event.Type == sf::Event::KeyPressed)
{
switch(Event.Key.Code)
{
case sf::Key::A:
ship.Move(-1,0);
break;
}
}
if(Event.Type == sf::Event::KeyPressed)
{
switch(Event.Key.Code)
{
case sf::Key::W:
ship.Move(0,-1);
break;
}
}
if(Event.Type == sf::Event::KeyPressed)
{
switch(Event.Key.Code)
{
case sf::Key::D:
ship.Move(1,0);
break;
}
}
if(Event.Type == sf::Event::KeyPressed)
{
switch(Event.Key.Code)
{
case sf::Key::S:
ship.Move(0,1);
break;
}
}
if(Event.Type == sf::Event::KeyPressed)
{
switch(Event.Key.Code)
{
case sf::Key::Q:
ship.Rotate(-1.f);
break;
}
}
if(Event.Type == sf::Event::KeyPressed)
{
switch(Event.Key.Code)
{
case sf::Key::E:
ship.Rotate(1.f);
break;
}
}
}
window.Clear(sf::Color::White);
window.Draw(ship);
window.Display();
}
return EXIT_SUCCESS;
}
-
so whats wrong with this code? it does the same?
You are using switch statements wrongly and are using multiple ifs when you should have just a single.
i was initially asking though that the front of the "image" always maintain 'W'
so if the user held S the ship goes down, the ship turns downwards, and if the user held D the ship turned right and moved right? all the times i tried the ship moves in the direction that i wanted but doesnt stop turning?
Ok, I read that like 5 times and I still am not really sure what you are asking. If you want anything beyond basically moving around the screen, you are going to need to implement a direction vector and velocity. If you want to change it so input isn't one to one ( ie, a keypress == a move ), you need to switch your input logic substantially.
-
is there anything wrong with this, it appears to be working?
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Test");
sf::Image Image;
if (!Image.LoadFromFile("ship.png"))
return EXIT_FAILURE;
sf::Sprite ship(Image);
ship.SetColor(sf::Color(50, 50, 50, 255));
ship.SetPosition(200.f, 100.f);
ship.SetScale(0.f,0.f);
ship.Rotate(0.f);
// Start game loop
while (window.IsOpened())
{
// Process events
sf::Event Event;
while (window.GetEvent(Event))
{
// Close window : exit
if (Event.Type == sf::Event::Closed)
window.Close();
if(Event.Type == sf::Event::KeyPressed)
{
switch(Event.Key.Code)
{
case sf::Key::A:
ship.SetRotation(270.f);
ship.Move(-5, 0);
break;
case sf::Key::W:
ship.SetRotation(180.f);
ship.Move(0,-5);
break;
case sf::Key::D:
ship.SetRotation(90.f);
ship.Move(5, 0);
break;
case sf::Key::S:
ship.SetRotation(0.f);
ship.Move(0,5);
break;
}
}
}
window.Clear(sf::Color::White);
window.Draw(ship);
window.Display();
}
return EXIT_SUCCESS;
}
-
Just some tips:
ship.SetScale(0.f,0.f);
ship.Rotate(0.f);
These are not needed. All sprites, when loaded have a scale of 0, and a rotation of 0. Also, the second line adds on degrees from what the rotation already is. You should be using SetRotation() to set the rotation to a set amount.
I have a question, though. When checking for what type an event is, should you use a if else or just if, because an event cant be both Closed and Mouse clicked(right?)