简体   繁体   中英

How can I setup SFML in Visual Studio 2017?

I don't know if this has happened to some of you guys. I haven't started programming because "I don't know where to start". I want to make a platform video game, and 8 bits one. Yeah it will take a lot of time and skill, but I always like to jump to the complicated stuff.

I'm the kind of person that likes to use the latest of the latest programs. So I use Visual Studio 2017, however SFML is up to VS2015. Is there a way to use SFML is VS2017? What can I do?

First, congrats on starting your journey into programming!

However, as someone who has tutored many kids who have the same ambition (eg learning C++ to make a video game), I'd recommend you start down a simpler path.

I won't go into trying to learn C# or Java or some other language, as I, and many others, actually started with C; it's not about learning the particular language, it's about understanding the system as a whole. The concept of a thread, object, loops or functions doesn't change, it's how it's utilized that changes between languages.

I'm the kind of person that likes to use the latest of the latest programs.

While this might typically be good for most programs, due to bug fixes or other enhancements, this is not true for development environments. When you update Visual Studio, you're typically updating your entire toolchain: compiler, linker, SDK's, etc.

This means the possibility to introduce either a buggy compiler, or have code flagged as deprecated, among other issues to be considered. Especially when developing something like a game.

I haven't started programming because "I don't know where to start"

Here's a simple "war" card game that emulates 2 players; it automatically plays war until the game is won. It repeats this until an interrupt signal is received ( CTRL + C ) and it prints out the maximum number of turns during any game, as well as the minimum number of turns in any game played by our 'auto-players'.

It's in C++, can be modified to take user input for a blackjack or poker game, and you can build it on any system simply enough.

This code is meant for teaching, so you can take this code, modify it, build it, run it, and understand what's happening in each of those steps.

From there, you can learn more, ask more questions, and eventually you'll be able to make your 2D platform game with SFML .

war.cpp

#include <iostream>
#include <string>
#include <sstream>
#include <deque>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include <csignal>

#define print(v) std::cout << v
#define printl(v) std::cout << v << std::endl

namespace util {
    class random {
        public:
            random() { std::srand(std::time(0)); }
            int get(int max_val) { return std::rand() % max_val; }
    };
}

namespace battle {
    class suit {
        public:
            typedef enum enum_t {
                HEART,
                DIAMOND,
                CLUB,
                SPADE,
                END
            } enum_t;

            suit() : m_val(END) {}
            suit(const suit& cp) : m_val(cp.m_val) {}
            explicit suit(enum_t val) : m_val(val) {}

            suit& operator=(const suit& other)
            {
                this->m_val = other.m_val;
                return *this;
            }
            suit& operator=(const enum_t& other)
            {
                this->m_val = other;
                return *this;
            }

            bool operator==(const enum_t& other) { return (this->m_val == other); }
            bool operator!=(const enum_t& other) { return (this->m_val != other); }
            bool operator<(const enum_t& other) { return (this->m_val < other); }
            bool operator>(const enum_t& other) { return (this->m_val > other); }
            operator int() const { return static_cast<int>(this->m_val); }
            operator enum_t() const { return this->m_val; }
            
            friend std::ostream& operator<<(std::ostream& os, const battle::suit& val)
            {
                switch (val.m_val) {
                    case battle::suit::HEART: os << "♥"; break;
                    case battle::suit::DIAMOND: os << "♦"; break;
                    case battle::suit::CLUB: os << "♣"; break;
                    case battle::suit::SPADE: os << "♠"; break;
                    default: os << '?'; break;
                }
                return os;
            }

        private:
            enum_t m_val;
    };
    
    class value {
        public:
            typedef enum enum_t {
                ACE,
                ONE,
                TWO,
                THREE,
                FOUR,
                FIVE,
                SIX,
                SEVEN,
                EIGHT,
                NINE,
                JACK,
                QUEEN,
                KING,
                END
            } enum_t;

            value() : m_val(END) {}
            value(const value& cp) : m_val(cp.m_val) {}
            explicit value(enum_t val) : m_val(val) {}

            value& operator=(const value& other)
            {
                this->m_val = other.m_val;
                return *this;
            }
            value& operator=(const enum_t& other)
            {
                this->m_val = other;
                return *this;
            }

            bool operator==(const enum_t& other) { return (this->m_val == other); }
            bool operator!=(const enum_t& other) { return (this->m_val != other); }
            bool operator<(const enum_t& other) { return (this->m_val < other); }
            bool operator>(const enum_t& other) { return (this->m_val > other); }
            operator int() const { return static_cast<int>(this->m_val); }
            operator enum_t() const { return this->m_val; }

            friend std::ostream& operator<<(std::ostream& os, const battle::value& val)
            {
                switch (val.m_val) {
                    case battle::value::ACE: os << 'A'; break;
                    case battle::value::JACK: os << 'J'; break;
                    case battle::value::QUEEN: os << 'Q'; break;
                    case battle::value::KING: os << 'K'; break;
                    default: os << static_cast<int>(val); break;
                }
                return os;
            }

        private:
            enum_t m_val;
    };

    class card {
        public:
            card() : m_val(value::END), m_suit(suit::END) {}
            card(const card& cp) : m_val(cp.m_val), m_suit(cp.m_suit) {}
            card(int suit, int val) : m_val(static_cast<value::enum_t>(val)), m_suit(static_cast<suit::enum_t>(suit)) {}
            card(suit::enum_t suit, value::enum_t val) : m_val(val), m_suit(suit) {}
            ~card() {}
            
            card& operator=(const card& other)
            {
                this->m_val = other.m_val;
                this->m_suit = other.m_suit;
                return *this;
            }
            
            bool operator==(const card& other)
            {
                return (this->m_val == other.m_val && this->m_suit == other.m_suit);
            }
            
            bool operator!=(const card& other)
            {
                return !(this->m_val == other.m_val && this->m_suit == other.m_suit);
            }
            
            bool operator<(const card& other)
            {
                if (this->m_val == value::ACE) {
                    return false;
                }
                return (this->m_val < other.m_val);
            }
            
            bool operator>(const card& other)
            {
                if (this->m_val == value::ACE) {
                    return (other.m_val != value::ACE);
                }
                return (this->m_val > other.m_val);
            }
            
            bool empty() const
            {
                return (this->m_val == value::END ||
                        this->m_suit == suit::END);
            }
            
            friend std::ostream& operator<<(std::ostream& os, const card& obj)
            {
                os << obj.m_val << obj.m_suit;
                return os;
            }
            
            int suit() const
            {
                return this->m_suit;
            }
            
            value::enum_t value() const
            {
                return this->m_val;
            }
            
        private:      
            battle::value m_val;
            battle::suit m_suit;
    };

    class deck {
        public:
            static const std::size_t DECK_SIZE = 52;
            static const std::size_t HALF_DECK = 26;

            deck() : m_rand(), m_deck() {}
            
            ~deck() {}
            
            bool add(card& c)
            {
                if (c.empty()) { return false; }
                const std::size_t idx = static_cast<std::size_t>(c.suit());
                itr_t cv = std::find(this->m_deck.begin(), this->m_deck.end(), c);
                bool found = (cv != this->m_deck.end());
                if (!found) {
                    this->m_deck.insert(this->m_deck.begin(), c);
                    return true;
                }
                return false;
            }
            
            void add_init(card c)
            {
                const std::size_t idx = static_cast<std::size_t>(c.suit());
                this->m_deck.push_back(c);
            }

            card deal()
            {
                if (!this->empty()) {
                    std::size_t cnt = this->m_deck.size();
                    if ((cnt == 0) || ((cnt - 1) == 0)) {
                        card ret(this->m_deck[0]);
                        this->m_deck.erase(this->m_deck.begin());
                        return ret;
                    }
                    cnt = this->m_rand.get(cnt);
                    card ret = this->m_deck[cnt];
                    this->remove_it(ret);
                    return ret;
                }
                return card();
            }
            
            bool empty() const
            {
                return this->m_deck.empty();
            }

            void fill()
            {
                printl("Filling deck");
                for (int s = suit::HEART; s < suit::END; ++s) {
                    for (int v = value::ACE; v < value::END; ++v) {
                        this->add_init(battle::card(s, v));
                    }
                }
            }

            void top_to_back()
            {
                card& c = this->m_deck[this->m_deck.size()-1];
                for (itr_t s = this->m_deck.begin(); s != this->m_deck.end(); ++s) {
                    if ((*s) == c) {
                        this->m_deck.erase(s);
                        break;
                    }
                }
                this->m_deck.insert(this->m_deck.begin(), c);
            }

            void remove(const card& c)
            {
                if (!this->empty()) {
                    this->remove_it(c);
                }
            }
            
            std::size_t size() const
            {
                return this->m_deck.size();
            }

            card operator[](std::size_t idx) const
            {
                return this->m_deck[idx];
            }
            
        private:
            deck(const deck& cp); // = delete
            deck& operator=(const deck& other); // = delete

            util::random m_rand;
            std::deque<card> m_deck;
            typedef std::deque<card>::iterator itr_t;
            
            void remove_it(const card& c)
            {
                for (itr_t s = this->m_deck.begin(); s != this->m_deck.end(); ++s) {
                    if ((*s) == c) {
                        this->m_deck.erase(s);
                        break;
                    }
                }
            }
    };

    class player {
        public:
            player() : m_hand(), m_name("NaN"), m_id(), m_tot_add(0), m_tot_rem(0), m_won(0), m_other(0) {}
            player(std::size_t id) : m_hand(), m_name(), m_id(id), m_tot_add(0), m_tot_rem(0), m_won(0), m_other(0)
            {
                std::stringstream ss;
                ss << "Player " << id;
                this->m_name = ss.str();
            }
        
            void add_init(card c)
            {
                this->m_hand.add_init(c);
            }
        
            bool add_card(card c)
            {
                ++this->m_tot_add;
                return this->m_hand.add(c);
            }
            
            void add_cards(const std::deque<card>& cards)
            {
                std::deque<card>::const_iterator start = cards.begin();
                while (start != cards.end()) {
                    this->add_card(*start);
                    ++start;
                }
            }
            
            bool empty() const
            {
                return this->m_hand.empty();
            }

            std::deque<card> battle_group() const
            {
                std::deque<card> ret;
                if (!this->empty()) {
                    std::size_t top_idx = this->m_hand.size()-1;
                    for (std::size_t i = 0; i < 4 && top_idx > 0; ++i) {
                        ret.push_back(this->m_hand[--top_idx]);
                    }
                }
                return ret;
            }
            
            std::size_t hand_size() const
            {
                return this->m_hand.size();
            }

            std::size_t id() const
            {
                return this->m_id;
            }
            
            std::string name() const
            {
                return this->m_name;
            }
            
            void print_hand() const
            {
                for (std::size_t i = 0; i < this->m_hand.size(); ++i) {
                    std::cout << this->m_hand[i] << std::endl;
                }
            }
            
            void remove_card(card c)
            {
                ++this->m_tot_rem;
                this->m_hand.remove(c);
            }
            
            void remove_cards(const std::deque<card>& cards)
            {
                std::deque<card>::const_iterator start = cards.begin();
                while (start != cards.end()) {
                    this->remove_card(*start);
                    ++start;
                }
            }
            
            void print_stats()
            {
                printl("---" << this->name() << "---");
                printl("Hand: " << this->m_hand.size());
                printl("Wins: " << this->m_won);
                printl("Took: " << this->m_tot_add);
                printl("Lost: " << this->m_tot_rem);
            }
            
            void set_other_play(player& other)
            {
                this->m_other = &other;
            }

            void takes(card& c)
            {
                printl(this->m_name << " takes " << c);
                this->m_hand.top_to_back();
                this->m_other->remove_card(c);
                this->add_card(c);
            }

            card top_card() const
            {
                if (this->empty()) { return card(); }
                return this->m_hand[this->m_hand.size()-1];
            }

            void won_battle(card& c)
            {
                printl(this->m_name << " won the battle!");
                this->takes(c);
                ++this->m_won;
            }

            void won_battle(const std::deque<card>& cards)
            {
                std::deque<card>::const_iterator start = cards.begin();
                this->m_hand.top_to_back();
                print(this->m_name << " won the battle, takes");
                while (start != cards.end()) {
                    print(" " << *start);
                    this->m_other->remove_card(*start);
                    this->add_card(*start);
                    ++start;
                }
                printl("");
                ++this->m_won;
            }

        private:
            deck m_hand;
            std::string m_name;
            std::size_t m_id;
            std::size_t m_tot_add;
            std::size_t m_tot_rem;
            std::size_t m_won;
            player* m_other;
    };

    class game {
        public:
            game() : m_deck(), m_p1(1), m_p2(2), m_turns(0), m_battles(0)
            {
                this->m_p1.set_other_play(this->m_p2);
                this->m_p2.set_other_play(this->m_p1);
                this->m_deck.fill();
                printl("Dealing cards");
                for (std::size_t i = 0; i < deck::HALF_DECK; ++i) {
                    this->m_p1.add_init(this->m_deck.deal());
                    this->m_p2.add_init(this->m_deck.deal());
                }
            }

            std::size_t dobattle(battle::card& c1, battle::card& c2)
            {
                printl("BATTLE!!!!");
                ++this->m_battles;
                std::size_t sz1 = this->m_p1.hand_size();
                std::size_t sz2 = this->m_p2.hand_size();
                if (sz2 <= 1 && sz1 > 1) {
                    this->m_p1.won_battle(c2);
                    return this->m_p1.id();
                }
                if (sz1 <= 1 && sz2 > 1) {
                    this->m_p2.won_battle(c1);
                    return this->m_p2.id();
                }

                std::deque<battle::card> t1 = this->m_p1.battle_group();
                std::deque<battle::card> t2 = this->m_p2.battle_group();
                printl(this->m_p1.name() << ": " << t1.back() << ", " << this->m_p2.name() << ": " << t2.back());
                if (t1.back() > t2.back()) {
                    this->m_p1.won_battle(t2);
                    return this->m_p1.id();
                } else if (t1.back() < t2.back()) {
                    this->m_p2.won_battle(t1);
                    return this->m_p2.id();
                } else { // another battle

                    this->m_p1.remove_card(c1); this->m_p1.remove_cards(t1);
                    this->m_p2.remove_card(c2); this->m_p2.remove_cards(t2);

                    if (this->dobattle(t1.back(), t2.back()) == this->m_p1.id()) {
                        this->m_p1.add_card(c1); this->m_p1.add_cards(t1);
                        this->m_p2.add_card(c2); this->m_p2.add_cards(t2);

                        this->m_p1.won_battle(t2);
                        return this->m_p1.id();
                    } else {
                        this->m_p1.add_card(c1); this->m_p1.add_cards(t1);
                        this->m_p2.add_card(c2); this->m_p2.add_cards(t2);

                        this->m_p2.won_battle(t1);
                        return this->m_p2.id();
                    }
                }
                return 0;
            }

            void play()
            {
                battle::card c1, c2;
                while (true) {
                    if (this->check_win()) break;
                    c1 = this->m_p1.top_card();
                    c2 = this->m_p2.top_card();
                    printl(this->m_p1.name() << ": " << c1 << ", " << this->m_p2.name() << ": " << c2);
                    if (c1 < c2) {
                        this->m_p2.takes(c1);
                    } else if (c1 > c2) {
                        this->m_p1.takes(c2);
                    } else { // c1 == c2
                        this->dobattle(c1, c2);
                    }
                    ++this->m_turns;
                    if (this->check_win()) break;   
                }
                printl("");
                printl("Game over!");
                printl("");
            }

            void print_stats()
            {
                printl("----Stats----");
                printl("Turns: " << this->m_turns);
                printl("Battles: " << this->m_battles);
                this->m_p1.print_stats();
                this->m_p2.print_stats();
            }

            std::size_t turns() const { return this->m_turns; }
            std::size_t battles() const { return this->m_battles; }

        private:
            deck m_deck;
            player m_p1;
            player m_p2;
            std::size_t m_turns;
            std::size_t m_battles;

            bool check_win() const
            {
                if (this->m_p1.empty() || this->m_p2.empty()) {
                    if (this->m_p1.empty() && !this->m_p2.empty()) {
                        printl(this->m_p2.name() << " WINS!");
                    } else if (!this->m_p1.empty() && this->m_p2.empty()) {
                        printl(this->m_p1.name() << " WINS!");
                    } else {
                        printl("TIE?");
                    }
                    return true;
                }
                return false;
            }
    };
}

static volatile bool m_stop;

static void sig_hand(int sig) {
    if (sig == SIGINT) { m_stop = true; }
}

int main(int argc, char* argv[])
{
    std::size_t x = ~0;
    std::size_t n = 0;
    std::size_t g = 0;
    const std::size_t MAX = 8; // 7*4 = 28

    std::signal(SIGINT, sig_hand);

    while ((x > MAX) && !m_stop) {
        battle::game game;
        game.play();
        ++g;
        game.print_stats();
        if (game.turns() < x) {
            x = game.turns();
            std::cerr << "least: " << x << std::endl;
        }
        if (n < game.turns()) {
            n = game.turns();
            std::cerr << "most: " << n << std::endl;
        }
    }
    //printl("Done! Games played: " << g << ", Least turns: " << x << ", Most turns: " << n);

    std::cerr << "Done! Games played: " << g << ", Least turns: " << x << ", Most turns: " << n << std::endl;
    return 0;
}

Hope that can help.

Just a note to say SFML now works fine with VS2017.

I have version 2.5 binaries no need to compile.

See instructions here:

https://www.sfml-dev.org/tutorials/2.5/start-vc.php

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM