getLocalBounds alternative for Text Objects? (SFML) - c++

Trying to make buttons using SFML for Comp Sci final and really don't want to draw invisible sprites over every single button.
I found some solutions but they were all using older versions of sfml and those functions have since been removed or changed and not sure what they've been changed to.
while(window.isOpen()){
Event event;
while(window.pollEvent(event)){
switch(event.type)
{
case Event::Closed:
window.close();
cout << "Window Closed!" << endl;
break;
case Event::MouseButtonPressed:
if(event.mouseButton.button == Mouse::Left){
cout << " if(event.mouseButton.button == Mouse::Left){" << endl;
if(equationsButtonText.getLocalBounds().contains(event.mouseButton.x, event.mouseButton.y)){
cout << "This works!" << endl;
}
}
default:
break;
}
}
}
cout << " if(event.mouseButton.button == Mouse::Left){" << endl; was just to test how far into the loop it got.

getLocalBounds returns the bounds in the local coordinates of the text. You need to use getGlobalBounds to get it in world coordinates.
You also need to use the mapPixelToCoords method of your window to transform the coordinates of the mouse also to world coordinates.
It would be something like this:
if(equationsButtonText.getGlobalBounds().contains(window.mapPixelToCoords({event.mouseButton.x, event.mouseButton.y}))){
cout << "This works!" << endl;
}

Related

Check mouse wheel state SFML

In my program I wish to be able to know if the mouse wheel has been scrolled, and if so how much in what direction. Is this possible with C++ and SFML?
So far I have this:
if (sf::Event::MouseWheelEvent().delta != 0)
{
SimulationView.zoom(1 + (10 / sf::Event::MouseWheelEvent().delta));
}
But the second line never exicutes, even when I scroll the mouse wheel
You can read the mouse wheel as part of the event loop that is polled once per frame:
int main()
{
sf::RenderWindow window(sf::VideoMode(320, 256), "Title");
sf::Event event;
while(window.isOpen())
{
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
else if(event.type == sf::Event::MouseWheelMoved)
{
// display number of ticks mouse wheel has moved
std::cout << event.mouseWheel.delta << '\n';
}
}
window.clear();
// draw window here
window.display();
}
}
Note: For SFML 2.3
Thanks to #Hiura for pointing out that sf::Event::MouseWheelMoved is deprecated in SFML 2.3.
Use this instead:
if(event.type == sf::Event::MouseWheelScrolled)
{
if(event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel)
std::cout << "wheel type: vertical" << std::endl;
else if(event.mouseWheelScroll.wheel == sf::Mouse::HorizontalWheel)
std::cout << "wheel type: horizontal" << std::endl;
else
std::cout << "wheel type: unknown" << std::endl;
std::cout << "wheel movement: " << event.mouseWheelScroll.delta << std::endl;
std::cout << "mouse x: " << event.mouseWheelScroll.x << std::endl;
std::cout << "mouse y: " << event.mouseWheelScroll.y << std::endl;
}

How to perform same action as changing Windows 7 display from Landscape to Portrait

I need to write a program which programmatically changes the Landscape mode to Portrait of a touchscreen in Windows 7. The resolution is 1920 x 1080 and I thought I could switch the 1920 with the 1080 and use ChangeDisplaySettings or ChangeDisplaySettingsEx to make the change. but it doesn't work.
Windows CE has some sort of rotate feature, so I tried that. as in:
devmode.dmFields = DM_DISPLAYORIENTATION;
devmode.dmDisplayOrientation = DMDO_90;
ChangeDisplaySettingsEx(NULL,&devmode,NULL,CDS_RESET,NULL);
But that didn't work on a normal test desktop PC.
I can do this through Control Panel, Display, Screen Resolution, choose Portrait, so should I not be able to do via Windows API?
How can I make this change in code?
EDIT
I tried this code, but I get DISP_CHANGE_BADMODE returned by ChangeDisplaySettings.
#include <Windows.h>
#include <iostream>
int main() {
DEVMODE dm;
// initialize the DEVMODE structure
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
if (0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
{
std::cout << "Orientation\n";
switch(dm.dmDisplayOrientation) {
case DMDO_DEFAULT: std::cout << "DMDO_DEFAULT\n"; break;
case DMDO_90: std::cout << "DMDO_90\n"; break;
case DMDO_180: std::cout << "DMDO_180\n"; break;
case DMDO_270: std::cout << "DMDO_270\n"; break;
}
std::cout << "Panning height: " << dm.dmPanningHeight << '\n'
<< "Panning width: " << dm.dmPanningWidth << '\n';
std::cout << "Colour resolution: " << dm.dmBitsPerPel << " bits per pixel\n";
std::cout << "Height in pixels: " << dm.dmPelsHeight << '\n';
std::cout << "Width in pixels: " << dm.dmPelsWidth << '\n';
if(dm.dmPelsHeight > dm.dmPelsWidth) {
std::cout << "Screen should be rotated 90 degrees\n";
std::cout << "Do you want to rotate display 90 degrees? (y or n)\n";
char ch;
std::cin >> ch;
if(ch == 'y') {
// swap height and width
DWORD tmp = dm.dmPelsHeight;
dm.dmPelsHeight = dm.dmPelsWidth;
dm.dmPelsWidth = tmp;
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
// determine new orientation
switch (dm.dmDisplayOrientation)
{
case DMDO_DEFAULT:
dm.dmDisplayOrientation = DMDO_270;
break;
case DMDO_270:
dm.dmDisplayOrientation = DMDO_180;
break;
case DMDO_180:
dm.dmDisplayOrientation = DMDO_90;
break;
case DMDO_90:
dm.dmDisplayOrientation = DMDO_DEFAULT;
break;
default:
// unknown orientation value
// add exception handling here
break;
}
LONG ret = ChangeDisplaySettings(&dm, CDS_TEST); //0);
std::cout << "ChangeDisplaySettings returned " << ret << '\n';
switch(ret) {
case DISP_CHANGE_SUCCESSFUL: std::cout << "display successfully changed\n"; break;
case DISP_CHANGE_BADDUALVIEW: std::cout << "The settings change was unsuccessful because the system is DualView capable\n"; break;
case DISP_CHANGE_BADFLAGS: std::cout << "An invalid set of flags was passed in.\n"; break;
case DISP_CHANGE_BADMODE: std::cout << "The graphics mode is not supported.\n"; break;
case DISP_CHANGE_BADPARAM: std::cout << "An invalid parameter was passed in. This can include an invalid flag or combination of flags.\n"; break;
case DISP_CHANGE_FAILED: std::cout << "The display driver failed the specified graphics mode.\n"; break;
case DISP_CHANGE_NOTUPDATED: std::cout << "Unable to write settings to the registry.\n"; break;
case DISP_CHANGE_RESTART: std::cout << "The computer must be restarted for the graphics mode to work.\n"; break;
}
}
}
else
std::cout << "Screen orientation is just fine\n";
}
}
I saw an article on the web indicating that possibly it couldn't be done. But this code works.
#include <Windows.h>
#include <iostream>
int main(int argc, char* argv[]) {
DEVMODE dm;
// initialize the DEVMODE structure
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
// only change first/default display (index=0)
if (0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
{
std::cout << "Current orientation\n";
switch(dm.dmDisplayOrientation) {
case DMDO_DEFAULT: std::cout << "DMDO_DEFAULT\n"; break;
case DMDO_90: std::cout << "DMDO_90\n"; break;
case DMDO_180: std::cout << "DMDO_180\n"; break;
case DMDO_270: std::cout << "DMDO_270\n"; break;
}
std::cout << "Panning height: " << dm.dmPanningHeight << '\n'
<< "Panning width: " << dm.dmPanningWidth << '\n';
std::cout << "Colour resolution: " << dm.dmBitsPerPel << " bits per pixel\n";
std::cout << "Height in pixels: " << dm.dmPelsHeight << '\n';
std::cout << "Width in pixels: " << dm.dmPelsWidth << '\n';
if(argc != 2) {
std::cout << "Usage: rotate_screen <angle>. Angle values: 0, 90, 180, 270. Angles are rotation clockwise. Use 0 to revert back\n";
exit(0);
}
// parse parameter
int rotate = atoi(argv[1]); // should do something better and safer here
if(rotate != 0 && rotate != 90 && rotate != 180 && rotate != 270) {
std::cout << "incorrect rotation selected\n";
}
else {
// swap height and width
DWORD tmp = dm.dmPelsHeight;
dm.dmPelsHeight = dm.dmPelsWidth;
dm.dmPelsWidth = tmp;
// select fields which have changed
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYORIENTATION;
// set angle
switch(rotate) {
case 0: dm.dmDisplayOrientation = DMDO_DEFAULT; break;
case 90: dm.dmDisplayOrientation = DMDO_90; break;
case 180: dm.dmDisplayOrientation = DMDO_180; break;
case 270: dm.dmDisplayOrientation = DMDO_270; break;
default:
std::cout << "Something went wrong, aborting\n";
exit(0);
}
LONG ret = ChangeDisplaySettingsEx(NULL, &dm, NULL, 0, NULL); //CDS_RESET, NULL); //0);
std::cout << "ChangeDisplaySettingsEx returned " << ret << '\n';
switch(ret) {
case DISP_CHANGE_SUCCESSFUL: std::cout << "display successfully changed\n"; break;
case DISP_CHANGE_BADDUALVIEW:
std::cout << "The settings change was unsuccessful because the system is DualView capable\n";
break;
case DISP_CHANGE_BADFLAGS: std::cout << "An invalid set of flags was passed in.\n"; break;
case DISP_CHANGE_BADMODE: std::cout << "The graphics mode is not supported.\n"; break;
case DISP_CHANGE_BADPARAM: std::cout << "An invalid parameter was passed in. This can include an invalid flag or combination of flags.\n"; break;
case DISP_CHANGE_FAILED: std::cout << "The display driver failed the specified graphics mode.\n"; break;
case DISP_CHANGE_NOTUPDATED: std::cout << "Unable to write settings to the registry.\n"; break;
case DISP_CHANGE_RESTART: std::cout << "The computer must be restarted for the graphics mode to work.\n"; break;
}
}
} // enum worked
}

How to get my circle moving with keys

I am doing one of my first projects on SFML C++ and im trying to combine things now.
What im trying to do is having my Circle which i made with :
sf::CircleShape shape(50);
shape.setPosition(800, 450);
and
shape.setFillColor(sf::Color(100, 250, 50));
now i am trying to move it using W, A, S, D or arrow keys.
But i am not sure how to this, i tried several things like :
if (sf::Keyboard::IsKeyPressed(sf::Keyboard::Up))
Sprite.Move(spriteSpeed * App.GetFrameTime(), 0);
But i am not sure what im doing wrong, can someone help me?
Thanks in advance!
This is the code i have atm.
#include "stdafx.h"
#include<SFML/Graphics.hpp>
#include<string>
#include<iostream>
int main()
{
//Here we declare the render window so we can talk to it.
sf::RenderWindow window;
//sf::VideoMode is to set the size of the window
//The seconds parameter (the string) is for setting the title
//The style is to show/hide the close button and the title bar, or to set full screen
window.create(sf::VideoMode(1600, 900), " My First SFML Game", sf::Style::Titlebar | sf::Style::Close | sf::Style::Resize);
//----------------------------------wait for a key to be pressed-------------------------------------
//This shows a message that you should press a key
/*std::cout << "Press a key to continue." << std::endl;*/
//---------------------------------------------------------------------------------------------------
//----------------------------------Showing a message------------------------------------------------
//Define the messages that will be showed, and the display text
std::string message = "Hello my name is Jean-Paul van Houten";
std::string display = "";
int index = 0;
window.setKeyRepeatEnabled(false);
//----------------------------------------------------------------------------------------------------
sf::CircleShape shape(50);
shape.setPosition(800, 450);
//this while loop will only be called if the window is open.
while(window.isOpen())
{
//Define the event variable
sf::Event eventSF;
//Check if there is an event
while(window.pollEvent(eventSF))
{
shape.setFillColor(sf::Color(100, 250, 50));
//shape.setPosition(eventSF.mouseMove.x 0 sha,eventSF.mouseMove.y);
window.clear();
switch(eventSF.type)
{
case sf::Event::Closed:
window.close();
break;
case sf::Event::MouseEntered:
std::cout << "Mouse within screen bounds" << std::endl;
break;
case sf::Event::MouseLeft:
std::cout << "Mouse outisde the screen bounds" << std::endl;
break;
case sf::Event::MouseMoved:
std::cout << "X: " << eventSF.mouseMove.y << " Y: " << eventSF.mouseMove.y << std::endl;
break;
case sf::Event::MouseButtonPressed:
if(eventSF.mouseButton.button == sf::Mouse::Left)
std::cout << "Left Button Pressed At: X: " << eventSF.mouseButton.x << " Y: " << eventSF.mouseButton.y << std::endl;
break;
case sf::Event::MouseWheelMoved:
std::cout << "Scrolled: " << eventSF.mouseWheel.delta << std::endl;
break;
case sf::Event::GainedFocus:
std::cout << "Window Active" << std::endl;
break;
case sf::Event::LostFocus:
std::cout << "Window Not Active" << std::endl;
break;
case sf::Event::Resized:
std::cout << "Width: " << eventSF.size.width << " Height: " << eventSF.size.height << std::endl;
break;
case sf::Event::TextEntered:
if(eventSF.text.unicode != 8)//(eventSF.text.unicode >= 33 && eventSF.text.unicode <= 126) //This is to only include the characters between the number, now we use punctuation and letters.
std::cout << (char)eventSF.text.unicode;
else if(eventSF.text.unicode == 8)
display = display.substr(0, display.length() - 1);
system("cls");
std::cout << display;
break;
}
window.draw(shape);
//If you release a key
if(eventSF.type == sf::Event::KeyReleased)
{
//and this key is the enter key
if(eventSF.key.code == sf::Keyboard::Return)
{
display += message[index];
index ++;
system("cls"); //CLS on windows, clear on mac/linux
std::cout << display;
}
}
}
window.display();
}
}
First, you have to add the KeyPressed event handling inside the event poll switch, and inside, the code to move your sprite
switch(eventSF.type)
{
[...]
case sf::Event::KeyPressed:
if(eventSF.key.code == sf::Keyboard::Up)
{
shape.move(0, 1)
}
break;
}
Also,
shape.setFillColor(sf::Color(100, 250, 50));
shouldn't be inside the game loop.
And this
window.clear();
window.draw(shape);
window.display();
should be outside the event poll loop:
while(window.isOpen())
{
//Define the event variable
sf::Event eventSF;
//Check if there is an event
while(window.pollEvent(eventSF))
{
[...]
}
window.clear();
window.draw(shape);
window.display();
}

C++ I cant access the functions i need to

I am trying to create a text based adventure game in c++ for my school project. The roblem i am having is that my gameover() function needs to be able to goto my begin() function. The problem is begin must be declared before before the gameover() function to allow it to go to begin(), only i have other functions that also need to access gameover(. In short i need a way to be able to tell my program to goto the function gameover() or begin(), and know that it exists and is declared.
Thanks, Simon
void begin() {
int name;
int choice1;
system("cls");
cout << "To start your adventure, please enter your name." << endl;
cin >> name;
cin.ignore();
system("cls");
cout << "Hello " << name << " Your adventure now begins.... Who knows what's in store for you!" << endl;
system("pause");
system("cls");
cout << "You find yourself in a dark, cramp library. " << endl;
cout << "You don't know how you got here, or where you are." << endl;
cout << "Luckily there is a sword laying on the ground next to you \nand an open door in front.\n" << endl;
cout << "What will you do?" << endl;
cout << "1. Pick up the sword" << endl;
cout << "2. Walk forward through the door" << endl;
cout << "3. Use the sword to end your miserable existence!" << endl;
cin >> choice1;
cin.ignore();
system("cls");
if (choice1 == 1) {
cout << "You quickly pick up the sword and run through the door." << endl;
system("pause");
road();
}
else if (choice1 == 2) {
cout << "While you make you way to the door...." << endl;
cout << "You somehow managed to trip on the sword." << endl;
cout << "You fall on the hilt smashing your neck, and end your painfully short life. " << endl;
system("pause");
gameover();
}
else {
cout << "That wasn't an option....." << endl;
cout << "You have now broken the game. Good day Sir!!!" << endl;
}
}
void gameover() {
int choice_b;
cout << " Oops! You died.... Try Again." << endl;
cout << "\n1. Start Again!" << endl;
cout << "2. Exit" << endl;
cin >> choice_b;
cin.ignore();
system("cls");
if (choice_b == 1) {
begin();
}
else if (choice_b == 2) { std::exit; }
}
C++ require you to describe the function before its calling statement. if you are going to add definition at top of main() then its call statement will work anywhere and second option is to declaration of function before calling. Its up to you that where you want that function to accessible.
Basically if you add some declaration in header file or in top of main then these functions will work anywhere
#include headerfiles....
void begin(); //
void end(); // Function prototypes
int main()
{
.....
begin(); // Will work here
}
Add the header file containing the declaration of fucntion begin and gameover or add declaration by yourself by adding void begin(); and void gameover() before their first use.
You should just add a function declaration like this in the top of the file (or above the gameover() function):
void begin();
The solution is to decouple the gameover and begin functions. Consider this:
bool continueGame = true;
void gameover()
{
//your gameover code
if (userChoosesToExit) continueGame = false;
}
void begin()
{
//your begin code
if (playerDies) gameover();
}
void controllerFunction()
{
while (continueGame)
{
begin();
}//while
}//controller
This way, after gameover, the program control will exit the begin function and if continueGame is still true, the while loop will continue looping and begin will be called again. This way, you'll also be able to call the begin and gameover functions whenever you want, from the controllerFunction. It's just a matter of logic structuring. With this hint, you'll be able to come up with a logic that's smarter than what I posted.
Your code is unnecessarily recursive: begin() calling gameover() calling begin() calling...
It would be better to have an outer loop that calls the necessary functions, like
int gameover()
{ // ...
// if (choice_b == 1) {
// begin();
// }
// else if (choice_b == 2) { std::exit; }
return choice_b;
}
int i = 0;
while (i != 2)
{ begin();
// ...
i = gameover();
}

Events using SDL 2.0

I wrote a simple SDL program using SDL 2.0. I have a little problem when I want to check the mouse wheel events. Actually, in the version 2.0 the flags SDL_BUTTON_WHEELDOWN and SDL_BUTTON_WHEELUP no longer exist. There is just the flags SDL_MOUSEWHEEL. The code below check correctly the' WHEELUP' and 'WHEELDOWN' events but with the same flag.
while(!terminer)
{
while (SDL_PollEvent(&evenements))
{
switch (evenements.type)
{
case SDL_QUIT:
terminer = true;
break;
case SDL_KEYDOWN:
switch (evenements.key.keysym.sym)
{
case SDLK_ESCAPE:
terminer = true;
break;
}
break;
case SDL_MOUSEMOTION:
std::cout << "MOUSE : MOVE" << std::endl;
break;
case SDL_MOUSEBUTTONUP:
case SDL_MOUSEBUTTONDOWN:
std::cout << "MOUSE : BUTTON DOWN" << std::endl;
break;
case SDL_MOUSEWHEEL:
std::cout << "MOUSE : WHEEL" << std::endl;
break;
}
}
But I would like to handle separately the 'WHEELUP' and 'WHEELDOWN' events. I tried several others flags in my condition but without success. Does anyone can help me?
You can catch the up and down event this way:
case SDL_MOUSEWHEEL:
if (evenements.wheel.y < 0)
std::cout << "MOUSE : WHEEL DOWN" << std::endl;
else
std::cout << "MOUSE : WHEEL UP" << std::endl;
break;