SFML - Code review

I would like to stop here and see if any of you can find anything that needs improving before I continue adding new stuff. In my personal opinion I like that the animation works well for a first time attempt. One thing I don't like is how the keyboard is being handled I think it needs improving with something neater and a little more responsive.

Anyway let me know if I'm heading in the right direction or I need to re think my ideas. Thanks in advance.

GFX.H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
 #ifndef GFX_H
#define GFX_H

#include <SFML/Graphics.hpp>

#include <iostream>
#include <string>

class TextureHandler
{
private:
    std::vector<sf::Texture*> textures;
public:
    TextureHandler() {}
    ~TextureHandler() { for(auto i : textures) delete i; }
    bool LoadTexture(std::string filename)
    {
        sf::Texture* t = new sf::Texture();
        if(!t->loadFromFile(filename)) return 0;
        textures.push_back(t);
        return 1;
    }

    sf::Texture& GetTexture(size_t location) const
    {
        if(location >= textures.size()) throw;
        return *textures[location];
    }
};

class Animation
{
private:
    std::string name;
    std::vector<sf::IntRect> frames;
    sf::Clock clock;
    sf::Time frame_length;
    size_t current_frame;
    bool is_playing;
public:
    Animation(std::string n, sf::Time fl): name(n), frame_length(fl), current_frame(0), is_playing(0) {}
    void AddFrame(int sx, int sy, int fx, int fy) { frames.push_back(sf::IntRect(sx,sy,fx,fy)); }
    void Update()
    {
        if(!is_playing) return;
        if(clock.getElapsedTime() < frame_length) return;
        if(current_frame+1 >= frames.size()) current_frame = 0;
        else current_frame++;
        clock.restart();
    }
    sf::IntRect& GetCurrentFrame() { return frames[current_frame]; }
    void Start()
    {
        if(!is_playing)
        {
            is_playing = true; clock.restart();
        }
    }
    void Stop() { if(is_playing) is_playing = false; current_frame = 0; }
    const bool IsPlaying() { return is_playing; }
};

#endif // GFX_H


MAIN.CPP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <SFML/Graphics.hpp>

#include <iostream>
#include <vector>

#include "gfx.h"

void HandleScroll(sf::Event event, sf::RenderWindow& window)
{
    static sf::View view(sf::Vector2f(0,0),sf::Vector2f(400,400));

    if(event.mouseWheelScroll.delta == 1) view.zoom(1.050);
    else if(event.mouseWheelScroll.delta == -1) view.zoom(0.950);

    window.setView(view);
}

enum direction {South, West, East, North};

class Player
{
private:
    std::vector<sf::Texture*> textures;
    size_t current_texture;
    std::vector<Animation> animations;
    size_t current_animation;
    sf::Sprite sprite;
    bool key_input;

public:
    Player(std::vector<sf::Texture*> t, std::vector<Animation> a)
    : textures(t), current_texture(0), animations(a), current_animation(0), key_input(0)
    {
        sprite.setTexture(*textures[current_texture]);
        sprite.setTextureRect(animations[current_animation].GetCurrentFrame());
    }
    void Draw(sf::RenderWindow* window) { window->draw(sprite); }
    void Update()
    {
        if(key_input) HandleKeyboard(); // Get keyboard input
        // Update sprite animation
        animations[current_animation].Update();
        sprite.setTextureRect(animations[current_animation].GetCurrentFrame());
    }
    void EnableKeyboard() { key_input = true; }
    void HandleKeyboard()
    {
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
        {
            if(current_animation != direction::North)
            {
                animations[current_animation].Stop();
                current_animation = direction::North;
            }
            if(!animations[current_animation].IsPlaying()) animations[current_animation].Start();
            sprite.move(0,-1);
        }
        else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
        {
            if(current_animation != direction::South)
            {
                animations[current_animation].Stop();
                current_animation = direction::South;
            }
            if(!animations[current_animation].IsPlaying()) animations[current_animation].Start();
            sprite.move(0,1);
        }
        else if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
        {
            if(current_animation != direction::West)
            {
                animations[current_animation].Stop();
                current_animation = direction::West;
            }
            if(!animations[current_animation].IsPlaying()) animations[current_animation].Start();
            sprite.move(-1,0);
        }
        else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
        {
            if(current_animation != direction::East)
            {
                animations[current_animation].Stop();
                current_animation = direction::East;
            }
            if(!animations[current_animation].IsPlaying()) animations[current_animation].Start();
            sprite.move(1,0);
        }
        else
        {
            animations[current_animation].Stop();
            key_input = false;
        }
    }
};

int main()
{
    // Variable and Object declarations
    sf::RenderWindow window(sf::VideoMode::getDesktopMode(),"Test");
    window.setFramerateLimit(60);

    // Initialising texture handler
    TextureHandler texture_handler;
    if(!texture_handler.LoadTexture("nannyogg.PNG"))
    {
        std::cout << "Could not load texture: nannyogg.PNG";
        return 1;
    }
    texture_handler.GetTexture(0).setSmooth(true);

    // Initialising animations
    std::vector<Animation> animation_sheet;
    for(size_t y = 0; y < texture_handler.GetTexture(0).getSize().y; y+=48 )
    {
        Animation animation("walking",sf::milliseconds(250));
        for(size_t x = 0; x < texture_handler.GetTexture(0).getSize().x; x+=32)
            animation.AddFrame(x,y,31,48);
        animation_sheet.push_back(animation);
    }

    // Creating Player object
    Player player({&texture_handler.GetTexture(0)},animation_sheet);

    // Main loop
    while(window.isOpen())
    {
        // Event loop
        sf::Event event;
        while(window.pollEvent(event))
        {
            switch(event.type)
            {
            case sf::Event::EventType::Closed:                  window.close(); break;
            case sf::Event::EventType::KeyPressed:
            case sf::Event::EventType::KeyReleased:             player.EnableKeyboard(); break;
            case sf::Event::EventType::MouseWheelScrolled:      HandleScroll(event,window); break;
            }
        }
        // Update section
        player.Update();
        // Graphics rendering
        window.clear(sf::Color::White);
        player.Draw(&window);
        window.display();
    }
    return 0;
}


Wish I could add "code spoilers" so they don't take up half the page.
Last edited on
Topic archived. No new replies allowed.