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;
}
Related
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;
}
So I am using SFML and c++ to create a simple space game. For the life of can't get a bullet to spawn. This is my source... I am just trying to learn how to go about spawning new sprites into a game.
```
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
#include <string>
int main()
{
// Create the main window
sf::RenderWindow app(sf::VideoMode(800, 600), "SFML window");
// Load a sprite to display
sf::Texture texture_sprite;
if (!texture_sprite.loadFromFile("cb.bmp"))
return EXIT_FAILURE;
sf::Sprite sprite(texture_sprite);
sf::Texture texture_background;
if (!texture_background.loadFromFile("space.png"))
return EXIT_FAILURE;
sf::Sprite background(texture_background);
sf::Texture texture_fire;
if (!texture_background.loadFromFile("fire_1.png"))
return EXIT_FAILURE;
sf::Sprite fire_sprite(texture_fire);
fire_sprite.setScale(4.0f, 1.6f);
std::string direction = "";
bool fire = false;
// Start the game loop
while (app.isOpen())
{
// Process events
sf::Event event;
while (app.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
app.close();
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left) && sprite.getPosition().x > -20)
{
sprite.move(-10,0);
std::cout << "X = " << sprite.getPosition().x << std::endl;
std::cout << "Y = " << sprite.getPosition().y << std::endl;
direction = "Left";
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right) && sprite.getPosition().x < 670 )
{
sprite.move(10,0);
std::cout << "X = " << sprite.getPosition().x << std::endl;
std::cout << "Y = " << sprite.getPosition().y << std::endl;
direction = "Right";
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up) && sprite.getPosition().y > 0)
{
sprite.move(0,-10);
std::cout << "X = " << sprite.getPosition().x << std::endl;
std::cout << "Y = " << sprite.getPosition().y << std::endl;
direction = "Up";
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down) && sprite.getPosition().y < 480 )
{
sprite.move(0,10);
std::cout << "X = " << sprite.getPosition().x << std::endl;
std::cout << "Y = " << sprite.getPosition().y << std::endl;
direction = "Down";
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
{
fire = true;
}
else if (event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::Space)
{
fire = false;
}
if(fire == true)
{
std::cout << "FIRE!!!" << std::endl;
fire_sprite.setPosition((sprite.getPosition()));
std::cout << "Fire positions is " <<fire_sprite.getPosition().x << " " << fire_sprite.getPosition().y << "The direction is " << direction <<std::endl;
}
}
app.clear();
// Draw the sprite
app.draw(background);
app.draw(sprite);
app.draw(fire_sprite);
// Update the window
app.display();
}
return EXIT_SUCCESS;
}
```
sf::Texture texture_fire;
if (!texture_background.loadFromFile("fire_1.png"))
Instead of loading texture to texture_fire you load again to texture_background. It should be:
if (!texture_fire.loadFromFile("fire_1.png"))
I'm doing a game in C++ with SFML and I want to draw on the screen an ice-ball and see it "walking" on the screen when I press the left mouse button. But when I press the button it doesn't draw the ice-ball. Have you got some answers to fix the problem?
Main:
#include <iostream>
#include <SFML/Graphics.hpp>
#include <string>
int main(int argc, char* argv[])
{
sf::RenderWindow window;
window.create(sf::VideoMode(1320, 840), "Game");
window.setFramerateLimit(60);
window.setVerticalSyncEnabled(true);
sf::Color color(255, 255, 255, 100);
sf::Time time = sf::seconds(2);
sf::Clock clock;
sf::Time time2 = clock.getElapsedTime();
std::cout << time.asSeconds() << std::endl;
std::cout << time2.asSeconds() << std::endl;
//clock.restart();
//TEXTURE
sf::Texture bgTexture;
if (!bgTexture.loadFromFile("file", sf::IntRect(0, 0, 1320, 840)))
{ std::cout << "Error: background not loaded" << std::endl; }
sf::Texture pTexture;
if (!pTexture.loadFromFile("file", sf::IntRect(0, 0, 32, 32)))
{ std::cout << "Error: player not loaded" << std::endl; }
sf::Texture ibTexture;
if (!ibTexture.loadFromFile("file"))
{ std::cout << "Error: ice-ball not loaded" << std::endl; }
//SPRITE
sf::Sprite background;
background.setTexture(bgTexture);
sf::Sprite player;
player.setTexture(pTexture);
player.setScale(2, 2);
player.setPosition(628, 388);
sf::Sprite iceBall;
iceBall.setTexture(ibTexture);
iceBall.setScale(1.5, 1.5);
//FONT
sf::Font font;
if (!font.loadFromFile("file"))
{ std::cout << "Error: font not loaded" << std::endl; }
//TEXT
sf::Text commands;
commands.setFont(font);
commands.setCharacterSize(54);
commands.setColor(sf::Color::Black);
commands.setString("D=Right \nA=Left \nW=Up \nS=DWON \n(also the arrows)");
commands.setPosition(213, 123);
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
{ window.close(); }
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::D || event.key.code == sf::Keyboard::Right)
{ player.move(10, 0); }
else if (event.key.code == sf::Keyboard::A || event.key.code == sf::Keyboard::Left)
{ player.move(-10, 0); }
else if (event.key.code == sf::Keyboard::W || event.key.code == sf::Keyboard::Up)
{ player.move(0, -10); }
else if (event.key.code == sf::Keyboard::S || event.key.code == sf::Keyboard::Down)
{ player.move(0, 10); }
}
/*if (event.type == sf::Event::MouseMoved)
{
std::cout << "X: " << event.mouseMove.x << " y: " << event.mouseMove.y << std::endl;
}*/
if (event.type == sf::Event::MouseButtonPressed) {
if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
std::cout << "Left mouse button pressed" << std::endl;
iceBall.setPosition(event.mouseMove.x, event.mouseMove.y);
window.draw(iceBall);
iceBall.move(event.mouseMove.x++, event.mouseMove.y++);
}
}
}
window.clear(color);
window.draw(background);
window.draw(player);
window.draw(commands);
window.display();
}
return 0;
}
Let's look at the workflow of your program:
you handle events, and depending on the left button status you draw the ice ball.
then, after event handling, you clear the screen and draw some more stuff.
Hence, you never actually display the ball.
Instead, structure your program as follows:
while (window.isOpen) {
sf::Event event;
while (window.pollEvent(event)) {
// Handle event & game *logic* here -- not drawing
// e.g. move entities
if (event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left) {
iceBall.setPosition(event.mouseButton.x, event.mouseButton.y);
// CAREFUL HERE: you mixed wrong element of the union event.
}
}
// Draw everything here
window.clear();
window.draw(background);
window.draw(player);
window.draw(iceBall);
window.draw(command);
window.display();
}
Additional note: in your code you used event.mouseMove while the type of event was NOT a mouse move. This is invalid. Checkout out the tutorial, especially this note:
Read the above paragraph once again and make sure that you fully understand it, the sf::Event union is the cause of many problems for inexperienced programmers.
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();
}
I'm a noob to SFML networking, i think i'm doing it all wrong, i'm constantly getting errors with this code. All i want to do is send packets of the position then update them on the other window, here is what i have so far.
#include <iostream>
#include <string>
#include "player.h"
#include "gameAssets.h"
#include "zombie.h"
using namespace std;
sf::Vector2u size(1000, 800);
bool focused = true;
sf::Vector2f newPosition, oldPosition;
//Multiplayer code.
//sf::Thread* thread = 0;
char choice;
sf::Mutex globalMutex;
sf::TcpSocket socket;
sf::IpAddress ip;
void sendandReceiveData(){
//Server half
sf::Packet packetSendX, packetSendY;
packetSendX << oldPosition.x;
packetSendY << oldPosition.y;
socket.send(packetSendX);
socket.send(packetSendY);
sf::Packet packetReceiveX, packetReceiveY;
//Client half
socket.receive(packetReceiveX);
socket.receive(packetReceiveY);
packetReceiveX >> newPosition.x;
packetReceiveY >> newPosition.y;
cout << "Other Players X: " << newPosition.x << endl;
cout << "Other Players Y: " << newPosition.y << endl;
}
int main(){
sf::RenderWindow window(sf::VideoMode(size.x, size.y), "Zombie Defence", sf::Style::Titlebar | sf::Style::Close);
//Limited fps so we dont need deltaTime...
window.setFramerateLimit(60);
window.setVerticalSyncEnabled(true);
player player;
zombie zombie;
gameAssets gameAssets;
player.initialize();
zombie.initialize();
gameAssets.initialize();
gameAssets.loadContent();
zombie.loadContent();
player.loadContent();
//Multiplayer code.
system("CLS");
cout << "Multiplayer Dev Build 0.1" << endl;
cout << " " << endl;
cout << "Enter (S) for server or (C) for client." << endl;
cin >> choice;
if (choice == 'S'){
sf::TcpListener listener;
listener.setBlocking(false);
listener.listen(5000);
listener.accept(socket);
cout << "New Client Connected: " << socket.getRemoteAddress() << endl;
}
else if (choice == 'C'){
cin >> ip;
if (socket.connect(ip, 5000) == sf::Socket::Done){
cout << "Connected to server" << endl;
}
}
while (window.isOpen()){
sf::View view = player.getView();
sf::Vector2f playerPosition = player.getPosition();
sf::Event event;
while (window.pollEvent(event)){
if (event.type == sf::Event::Closed){
window.close();
}
if (event.type == sf::Event::GainedFocus){
focused = 1;
}
else if (event.type == sf::Event::LostFocus){
focused = 0;
}
}
//Only update if window is focused...
if (focused){
//Updating
player.update(window);
zombie.followPlayer(playerPosition);
zombie.update(window);
window.setView(view);
}
oldPosition = player.getPosition();
sendandReceiveData();
window.clear();
gameAssets.draw(window);
zombie.draw(window);
player.draw(window);
window.display();
}
return 0;
}
If anyone could give me a hand on what i'm doing wrong it would be appreciated, thanks.
I fixed it. All I had to do was add packetReceiveX.clear(); and the same for the y to fix the problem.