SFML Networking problems - c++

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.

Related

Problem with getting the correct player output

i was creating a tictactoe game and for the player vs player feature of the game I cant seem to wrap my head around getting the player symbols the correct way around.
I'm not really able to provide the minimum amount of code, as it would be my entire program, so I have grabbed the function. I belive it is something to do with the conditional operator but cant figure out what.
but some guy provided a compilable example for me :)
#include <iostream>
#include <string>
/* MOCK */
void print() {};
bool win() { return false; };
bool tie() { return false; };
void player_move() {};
void player_move2() {};
char player, player2;
std::string playerName, player2Name;
/********/
void pvp() {
while (true) {
std::cout << "Player 1 Name: ";
std::cin >> playerName;
std::cout << "Player 2 Name: ";
std::cin >> player2Name;
std::cout << "Which symbol (Player 1: X or player 2: O) goes first? ";
std::cin >> player;
if (player == 'X' || player == 'O') {
break;
}
}
player2 = player == 'O' ? 'X' : 'O';
if (player == 'O') {
player_move2();
}
print();
while (true) {
std::cout << playerName << "'s turn to make a move\n";
player_move();
print();
if (win()) {
std::cout << playerName << " wins!\n";
return;
} else if (tie()) {
std::cout << "Tie!\n";
return;
}
std::cout << player2Name << "'s turn to make a move\n";
player_move2();
print();
if (win()) {
std::cout << player2Name << " wins!\n";
return;
} else if (tie()) {
std::cout << "Tie!\n";
return;
}
}
}
int main() {
pvp();
}
EXPLANATION
There are some patterns in your code, e.g. "making a move":
std::cout << playerName << "'s turn to make a move\n";
player_move();
print();
if (win()) {
std::cout << playerName << " wins!\n";
return;
} else if (tie()) {
std::cout << "Tie!\n";
return;
}
Which is the same for player 1 and player 2, except that you call player2_move(), and display the name of player 2.
Your second loop can then be simplified as
while(true) {
// do_player1_move
// do_player2_move
}
You now come about the problem that the loop will always begin with player 1. To solve this, you're trying to do_player2_move before the loop, if player 2 shall start.
if (player == 'O') {
// do_player2_move
}
while(true) {
// do_player1_move
// do_player2_move
}
However, in your code you only call player2_move(), instead of the entire pattern "making a move" for player 2.
SOLUTION
Therefore, adjusting
if (player == 'O') {
player_move2();
}
to
if (player == 'O') {
std::cout << player2Name << "'s turn to make a move\n";
player_move2();
print();
if (win()) {
std::cout << player2Name << " wins!\n";
return;
} else if (tie()) {
std::cout << "Tie!\n";
return;
}
}
should solve your problem

Boost multi_array BOOST_ASSERT has thrown a breakpoint

I'm writing a texbased dungeoncrawler style game for my C++ class and I'm encountering a runtime error stating that boost assert has triggered a breakpoint. I've made a very similar project in C# using the same logic, so I think it's something to do with a specific of C++ that's causing my issue.
Here's my code:
ArtoriaClasses.h
#pragma once
//Jake Farley
//CSC275
//Artoria (Final)
//11/25/17
#include <iostream>
#include <sstream>
#include <memory>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/algorithm/string.hpp>
#include <string>
#include <ctime>
#include <vector>
#include <fstream>
#include "boost/multi_array.hpp"
#include <cassert>
using namespace std;
//Class representing one tile of the map
class MapTile
{
private:
int X;
int Y;
string message;
int eventID;
public:
//Default Constructor
MapTile()
{
}
//Constructor with minimum arguments
MapTile(int x, int y)
{
X = x;
Y = y;
message = "You are unable to go that way.";
eventID = -1;
}
//Constructor with all arguments
MapTile(int x, int y, string message, int eventID)
{
X = x;
Y = y;
this->message = message;
this->eventID = eventID;
}
//function to return coords as a vector with 2 elements
vector<int> getCoords()
{
vector<int> coords;
coords.push_back(X);
coords.push_back(Y);
return coords;
}
//function to get the message;
string getMessage()
{
return message;
}
//function to get the eventID
int getEventID()
{
return eventID;
}
};
//Class that is the game object itself, is implemented in the main "runner"
class Artoria
{
private:
int tempCoordinates[2];
int coordinates[2];
Player player;
Enemy currentEnemy;
bool activeEnemy;
//This is what I tried originally but it throws a bad_alloc at runtime
//when I first try to assign it a value in populateMap()
//MapTile map[10][10];
//Trying something for map
boost::multi_array<MapTile, 2> map2 { boost::extents[10][10] };
vector<Item> looseItems;
vector<Weapon> weapons;
vector<Armor> armors;
Random randomGen;
bool playerDied;
public:
//Default Constructor
Artoria()
{
populateItems();
populateMap();
activeEnemy = false;
startGame();
}
//Function that creates the entire map by populating the multidimensional array of MapTile objects
void populateMap()
{
map2[0][0] = MapTile(0, 0, "You cannot go this way.", -1);
//Omitted additional assignments to save character space
map2[9][9] = MapTile(9, 9, "You are in the Alchemists' Lab!", 3);
}
//Function to evaluate user's input
string evaluateInput(string userInput)
{
boost::algorithm::to_lower(userInput);
if (userInput == "north")
{
if (!activeEnemy)
{
//moving south so add one to Y coordinate
coordinates[1] = (coordinates[1] + 1);
}
else
{
cout << "You cannot move when there is an enemy attacking you!" << endl << "Type 'Attack' to attack the enemy. Type 'help_me' for detailed instructions." << endl;
return "false";
}
}
else if (userInput == "south")
{
if (!activeEnemy)
{
//moving south so subract one from Y coordinate
coordinates[1] = (coordinates[1] - 1);
}
else
{
cout << "You cannot move when there is an enemy attacking you!" << endl << "Type 'Attack' to attack the enemy. Type 'help_me' for detailed instructions." << endl;
return "false";
}
}
else if (userInput == "east")
{
if (!activeEnemy)
{
//moving east so add 1 to X coordinate
coordinates[0] = (coordinates[0] + 1);
}
else
{
cout << "You cannot move when there is an enemy attacking you!" << endl << "Type 'Attack' to attack the enemy. Type 'help_me' for detailed instructions." << endl;
return "false";
}
}
else if (userInput == "west")
{
if (!activeEnemy)
{
//moving west so subract 1 from X coordinate
coordinates[0] = (coordinates[0] - 1);
}
else
{
cout << "You cannot move when there is an enemy attacking you!" << endl << "Type 'Attack' to attack the enemy. Type 'help_me' for detailed instructions." << endl;
return "false";
}
}
else if (userInput == "attack")
{
if (activeEnemy)
{
battleEnemy();
}
else
{
cout << "There is no enemy attacking you, move around to find enemies." << endl << "Type 'help_me' for detailed instructions." << endl;
}
}
else if (userInput == "stopplayingartoria")
{
string ret = quitGame();
return ret;
}
else if (userInput == "help_me")
{
stringstream ret;
ret << "You can move around the map typing the following commands: 'north', 'south', 'east', and 'west'" << endl << "If you encounter an enemy, attack them by typing 'attack' If you wish to quit the game, type 'StopPlayingArtoria'" << endl;
}
else
{
return "false";
}
return "true";
}
//Function to generate the message output to the console.
string genMessage()
{
if (!activeEnemy)
{
//get the current map tile from the map container
MapTile currentTile = map2[coordinates[0]][coordinates[1]];
string message = currentTile.getMessage();
int eventID = currentTile.getEventID();
//string variable to fill with return value;
string retStr;
//3 different areas each with event id(1-3), event ids are added for additional custom events
switch (eventID)
{
case 1:
//Dungeon Hallway
retStr = genDungeonHallway();
cout << message << endl << retStr;
break;
case 2:
//Crypt
retStr = genCrypt();
cout << message << endl << retStr;
break;
case 3:
//Alchemist's Lab
retStr = genAlchemistsLab();
cout << message << endl << retStr;
break;
case 4:
retStr = "This appears to be a safe place, nothing can surprise you here, but you will also find nothing here.";
cout << message << retStr << endl;
break;
case -1:
//player cannot go here so reset his coordinates
coordinates[0] = tempCoordinates[0];
coordinates[1] = tempCoordinates[1];
return message;
default:
// Case 0 is just print message(currently unused)
retStr = message;
break;
}
//set tempCoords to keep track of last tile.
tempCoordinates[0] = coordinates[0];
tempCoordinates[1] = coordinates[1];
return retStr;
}
}
};
Runner.cpp
//Jake Farley
//CSC275
//Artoria (Final)
//11/25/17
#include <iostream>
#include <string>
#include <memory>
#include <boost/algorithm/string.hpp>
#include "ArtoriaClasses.h";
using namespace std;
int main()
{
string userInput;
cout << "Welcome to the game 'Artoria'. You can start a new game by typing 'new' " << endl << " load an existing save by typing 'load' or view instructions on how to play the game by typing 'help_me'" << endl;
getline(cin, userInput);
boost::algorithm::to_lower(userInput);
if (userInput == "new")
{
Artoria artoriaGame = Artoria();
while (userInput != "QUIT")
{
getline(cin, userInput);
string ret = artoriaGame.evaluateInput(userInput);
if (ret == "true")
{
cout << artoriaGame.genMessage();
}
else if (ret == "false")
{
cout << "You have entered an invalid command. You can type 'help_me' for instructions.";
}
else if (ret == "QUIT")
{
}
}
}
else if (userInput == "load")
{
cout << "What is the name you used?" << endl;
getline(cin, userInput);
Artoria artoriaGame = Artoria(userInput);
while (userInput != "QUIT")
{
getline(cin, userInput);
string ret = artoriaGame.evaluateInput(userInput);
if (ret == "true")
{
cout << artoriaGame.genMessage();
}
else if (ret == "false")
{
cout << "You have entered an invalid command. You can type 'help_me' for instructions.";
}
else if (ret == "QUIT")
{
}
}
}
else if (userInput == "help_me")
{
cout << "Artoria is a text-based dungeon crawler created by Jake Farley. The goal of the game is to get the highest score." << endl;
cout << "You score points by defeating monsters and picking up items, as you walk around the map you will encounter various enemies and find various items." << endl;
cout << "As you fight enemies, you will take damage; be warned, there is no way to regain your health. Once your health reaches zero, the game will end." << endl;
cout << "You can move around the map by typing the four compass directions 'north', 'south', 'east', and 'west'" << endl;
cout << "If you encounter an enemy, attack them by typing 'attack' you cannot run away from an enemy encounter." << endl;
cout << "If you wish to quit the game, type 'StopPlayingArtoria'" << endl;
}
else
{
cout << "Error: Invalid response, closing program." << endl;
}
system("pause");
}
What are the "omitted assignments"? If they address illegal indices, that would do it.
I don't see you initialize the coordinates anywhere, either. You probably think you get that for free, like in C#?
int tempCoordinates[2] = {0,0};
int coordinates[2] = {0,0};
It doesn't look like you do any range validation on the movements (west, east etc.), also look at the copy-paste comments ... :)
//moving south so add one to Y coordinate
coordinates[1] = (coordinates[1] + 1);
//moving south so subract one from Y coordinate
coordinates[1] = (coordinates[1] - 1);
//moving east so add 1 to X coordinate
coordinates[0] = (coordinates[0] + 1);
//moving west so subract 1 from X coordinate
coordinates[0] = (coordinates[0] - 1);
Suggestion
It would be better to abstract a little bit:
enum { Rows = 10, Columns = 10 };
struct Coords {
int x = 0, y = 0;
bool west() { if (x>0) { --x; return true; } return false; }
bool south() { if (y>0) { --y; return true; } return false; }
bool east() { if (x+1<Columns) { ++x; return true; } return false; }
bool north() { if (y+1<Rows) { ++y; return true; } return false; }
};
Coords lastCoordinates;
Coords coordinates;
Now you can use those constants:
boost::multi_array<MapTile, 2> map2 { boost::extents[Columns][Rows] };
And use them safe actions:
if (userInput == "north")
{
if (!activeEnemy)
{
coordinates.north();
}
// ...
No more need for comments, let alone wrong comments :)
Using it:
MapTile currentTile = map2[coordinates.x][coordinates.y];
Or:
case -1:
//player cannot go here so reset his coordinates
coordinates = lastCoordinates;
return message;
And:
//set lastCoordinates to keep track of last tile.
lastCoordinates = coordinates;
Live Demo
Managed to make navigation "playable". It reaches Alchemist Lab, just fine:
Live On Coliru
//#pragma once
//Jake Farley
//CSC275
//Artoria (Final)
//11/25/17
struct Player {
};
struct Enemy {
};
struct Item {
};
struct Weapon {
};
struct Armor {
};
#include <iostream>
#include <sstream>
#include <memory>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/algorithm/string.hpp>
#include <string>
#include <ctime>
#include <vector>
#include <fstream>
#include "boost/multi_array.hpp"
#include <cassert>
using Random = boost::random::mt19937;
using namespace std;
//Class representing one tile of the map
class MapTile
{
private:
int X;
int Y;
string message;
int eventID;
public:
//Default Constructor
MapTile()
{
}
//Constructor with minimum arguments
MapTile(int x, int y)
{
X = x;
Y = y;
message = "You are unable to go that way.";
eventID = -1;
}
//Constructor with all arguments
MapTile(int x, int y, string message, int eventID)
{
X = x;
Y = y;
this->message = message;
this->eventID = eventID;
}
//function to return coords as a vector with 2 elements
vector<int> getCoords()
{
vector<int> coords;
coords.push_back(X);
coords.push_back(Y);
return coords;
}
//function to get the message;
string getMessage()
{
return message;
}
//function to get the eventID
int getEventID()
{
return eventID;
}
};
//Class that is the game object itself, is implemented in the main "runner"
class Artoria
{
private:
enum { Rows = 10, Columns = 10 };
struct Coords {
int x = 0, y = 0;
bool west() { if (x>0) { --x; return true; } return false; }
bool south() { if (y>0) { --y; return true; } return false; }
bool east() { if (x+1<Columns) { ++x; return true; } return false; }
bool north() { if (y+1<Rows) { ++y; return true; } return false; }
};
Coords lastCoordinates;
Coords coordinates;
Player player;
Enemy currentEnemy;
bool activeEnemy;
boost::multi_array<MapTile, 2> map2 { boost::extents[Columns][Rows] };
vector<Item> looseItems;
vector<Weapon> weapons;
vector<Armor> armors;
Random randomGen;
bool playerDied;
public:
//Default Constructor
Artoria(std::string const& /*s*/ = {})
{
//populateItems();
populateMap();
activeEnemy = false;
//startGame();
}
//Function that creates the entire map by populating the multidimensional array of MapTile objects
void populateMap()
{
map2[0][0] = MapTile(0, 0, "You cannot go this way.", -1);
//Omitted additional assignments to save character space
map2[9][9] = MapTile(9, 9, "You are in the Alchemists' Lab!", 3);
}
//Function to evaluate user's input
string evaluateInput(string userInput)
{
boost::algorithm::to_lower(userInput);
if (userInput == "north")
{
if (!activeEnemy)
{
coordinates.north();
}
else
{
cout << "You cannot move when there is an enemy attacking you!" << endl << "Type 'Attack' to attack the enemy. Type 'help_me' for detailed instructions." << endl;
return "false";
}
}
else if (userInput == "south")
{
if (!activeEnemy)
{
coordinates.south();
}
else
{
cout << "You cannot move when there is an enemy attacking you!" << endl << "Type 'Attack' to attack the enemy. Type 'help_me' for detailed instructions." << endl;
return "false";
}
}
else if (userInput == "east")
{
if (!activeEnemy)
{
coordinates.east();
}
else
{
cout << "You cannot move when there is an enemy attacking you!" << endl << "Type 'Attack' to attack the enemy. Type 'help_me' for detailed instructions." << endl;
return "false";
}
}
else if (userInput == "west")
{
if (!activeEnemy)
{
coordinates.west();
}
else
{
cout << "You cannot move when there is an enemy attacking you!" << endl << "Type 'Attack' to attack the enemy. Type 'help_me' for detailed instructions." << endl;
return "false";
}
}
else if (userInput == "attack")
{
if (activeEnemy)
{
//battleEnemy();
}
else
{
cout << "There is no enemy attacking you, move around to find enemies." << endl << "Type 'help_me' for detailed instructions." << endl;
}
}
else if (userInput == "stopplayingartoria")
{
//string ret = quitGame();
return "quit";
}
else if (userInput == "help_me")
{
stringstream ret;
ret << "You can move around the map typing the following commands: 'north', 'south', 'east', and 'west'" << endl << "If you encounter an enemy, attack them by typing 'attack' If you wish to quit the game, type 'StopPlayingArtoria'" << endl;
}
else
{
return "false";
}
return "true";
}
//Function to generate the message output to the console.
string genMessage()
{
if (!activeEnemy)
{
//get the current map tile from the map container
MapTile currentTile = map2[coordinates.x][coordinates.y];
string message = currentTile.getMessage();
int eventID = currentTile.getEventID();
//string variable to fill with return value;
string retStr;
//3 different areas each with event id(1-3), event ids are added for additional custom events
switch (eventID)
{
case 1:
//Dungeon Hallway
retStr = "genDungeonHallway()";
cout << message << endl << retStr;
break;
case 2:
//Crypt
retStr = "genCrypt()";
cout << message << endl << retStr;
break;
case 3:
//Alchemist's Lab
retStr = "genAlchemistsLab()";
cout << message << endl << retStr;
break;
case 4:
retStr = "This appears to be a safe place, nothing can surprise you here, but you will also find nothing here.";
cout << message << retStr << endl;
break;
case -1:
//player cannot go here so reset his coordinates
coordinates = lastCoordinates;
return message;
default:
// Case 0 is just print message(currently unused)
retStr = message;
break;
}
//set lastCoordinates to keep track of last tile.
lastCoordinates = coordinates;
return retStr;
}
}
};
//Jake Farley
//CSC275
//Artoria (Final)
//11/25/17
#include <iostream>
#include <string>
#include <memory>
#include <boost/algorithm/string.hpp>
//#include "ArtoriaClasses.h";
using namespace std;
int main()
{
string userInput;
cout << "Welcome to the game 'Artoria'. You can start a new game by typing 'new' " << endl << " load an existing save by typing 'load' or view instructions on how to play the game by typing 'help_me'" << endl;
getline(cin, userInput);
boost::algorithm::to_lower(userInput);
if (userInput == "new")
{
Artoria artoriaGame = Artoria();
while (userInput != "QUIT")
{
getline(cin, userInput);
string ret = artoriaGame.evaluateInput(userInput);
if (ret == "true")
{
cout << artoriaGame.genMessage();
}
else if (ret == "false")
{
cout << "You have entered an invalid command. You can type 'help_me' for instructions.";
}
else if (ret == "QUIT")
{
}
}
}
else if (userInput == "load")
{
cout << "What is the name you used?" << endl;
getline(cin, userInput);
Artoria artoriaGame = Artoria(userInput);
while (userInput != "QUIT")
{
getline(cin, userInput);
string ret = artoriaGame.evaluateInput(userInput);
if (ret == "true")
{
cout << artoriaGame.genMessage();
}
else if (ret == "false")
{
cout << "You have entered an invalid command. You can type 'help_me' for instructions.";
}
else if (ret == "QUIT")
{
}
}
}
else if (userInput == "help_me")
{
cout << "Artoria is a text-based dungeon crawler created by Jake Farley. The goal of the game is to get the highest score." << endl;
cout << "You score points by defeating monsters and picking up items, as you walk around the map you will encounter various enemies and find various items." << endl;
cout << "As you fight enemies, you will take damage; be warned, there is no way to regain your health. Once your health reaches zero, the game will end." << endl;
cout << "You can move around the map by typing the four compass directions 'north', 'south', 'east', and 'west'" << endl;
cout << "If you encounter an enemy, attack them by typing 'attack' you cannot run away from an enemy encounter." << endl;
cout << "If you wish to quit the game, type 'StopPlayingArtoria'" << endl;
}
else
{
cout << "Error: Invalid response, closing program." << endl;
}
}
Prints
Welcome to the game 'Artoria'. You can start a new game by typing 'new'
load an existing save by typing 'load' or view instructions on how to play the game by typing 'help_me'
You cannot go this way.
You are in the Alchemists' Lab!
genAlchemistsLab()
genAlchemistsLab()
You have entered an invalid command.
You can type 'help_me' for instructions.
You have entered an invalid command. You can type 'help_me' for instructions.
You have entered an invalid command. You can type 'help_me' for instructions.
You have entered an invalid command. You can type 'help_me' for instructions.
You have entered an invalid command. You can type 'help_me' for instructions.
You have entered an invalid command. You can type 'help_me' for instructions.
You have entered an invalid command. You can type 'help_me' for instructions.
...
As you can see you need to work on the input loop and detecting end-of-file :)

SFML Bullet not spawning

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"))

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();
}

std::thread communication issue

I am building a multithreaded application, but I've got a problem.
In the application I'm using a variable to communicate between the threads but it does not work. So when you type in exit the application does not stop executing.
The code:
//Program that controls an cadrocopter with the use of a
//Raspberry Pi, MPU 6050, an ultrasonic sensor, an HMC5883L and Arduino Leonardo
//to compile use "g++ ./quad.cpp -o ./quad -std=c++0x -pthread"
//
//Copyright Jan Hendrik Farr
#include <iostream> //used to input data
#include <string> //used to procces the userdata
#include <stdlib.h> //used to convert strings into floats
#include "./serial/serial.h" //used to communicate with the Arduino
#include <thread> //used to do multithreating
using namespace std;
//userinterface thread
void userInterface(int cmdPos1, float cmdPos[]){
string cmd = "";
cout << "************************" << endl;
cout << "* Quadrocopter control *" << endl;
cout << "* software *" << endl;
cout << "* *" << endl;
cout << "* version 0.1 *" << endl;
cout << "* *" << endl;
cout << "* Copyright J.H. Farr *" << endl;
cout << "************************" << endl << endl << endl;
while(cmdPos1 != 4){
cin >> cmd;
if(cmd == "move"){
cin >> cmdPos[0] >> cmdPos[1] >> cmdPos[2] >> cmdPos[3];
cmdPos1 = 1;
cout << endl << endl;
} else if(cmd == "move+"){
cin >> cmdPos[0] >> cmdPos[1] >> cmdPos[2] >> cmdPos[3];
cmdPos1 = 2;
cout << endl << endl;
} else if(cmd == "land"){
cmdPos1 = 3;
cout << endl << endl;
} else if(cmd == "exit"){
cmdPos1 = 4;
cout << endl;
} else {
cout << "invalid argument!!" << endl << endl;
}
}
}
//algorithm
void algorithm(float tele[], int cmdPos1, float cmdPos[]){
while(cmdPos1 != 4){
switch (cmdPos1){
case 2:
cout << "works!!";
break;
case 1:
break;
case 3:
break;
}
}
}
//gets telemetrydata from mpu
void gettelempu(float tele[], int cmdPos1){
while(cmdPos1 != 4){
}
}
//gets height from ultrasonic sensor
void getheight(float tele[], int cmdPos1){
while(cmdPos1 != 4){
}
}
//main function
int main(){
//telemetry data
float tele[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
//what to do
int cmdPos1 = 0;
//where to go
float cmdPos[4] = {0, 0, 0, 0};
thread t1(userInterface, cmdPos1, cmdPos);
thread t2(algorithm, tele, cmdPos1, cmdPos);
thread t3(gettelempu, tele, cmdPos1);
thread t4(getheight, tele, cmdPos1);
t1.join();
t2.join();
t3.join();
t4.join();
return 0;
}
void gettelempu(float tele[], int cmdPos1)
This function gets its own copy of cmdPos; at the time when it's called, the value passed to it is 0, and the function never changes that value, so the loop never terminates. Same thing in algorithm and getheight.
In order to change the value of this argument in one place and have other functions see that change the functions have to take the value by reference:
void gettelempu(float tele[], int& cmdPos1)
and when the thread is created you have to pass a reference:
thread t3(gettelempu, tele, std::ref(cmdPos1));
But wait, there's more! There's no guarantee that changes to cmdPos1 that are made in one thread will be visible to other threads. To ensure this, make it atomic. In main, change
int cmdPos1 = 0;
to
std::atomic<int> cmdPos1 = 0;
and change the function signatures to take an std::atomic<int> instead of an int:
void gettelempu(float tele[], std::atomic<int>& cmdPos1)