-
Hello SFML community!
I've created a 40 minutes tutorial/screencast on the creation of a complete game using C++11 and SFML2.
The end result is a playable Arkanoid/Breakout clone with a paddle, a ball and destroyable bricks.
This is my first attempt at a complete C++11 game development tutorial.
I divided the code in 9 segments, that I analyze and execute individually.
The video is aimed at people with at least a basic knowledge of C++.
Having some knowledge about common game development concepts will also greatly help.
The point of the video is showing how easy it is to create something playable thanks to the new standard and thanks to SFML, and to show a possible train of thought that can be taken during game development.
http://www.youtube.com/watch?v=_4K3tsKa1Uc
I greatly appreciate comments and criticism, and ideas for future videos/tutorials.
Also, feel free to fork the game's source code at:
https://github.com/SuperV1234/Tutorials
and expand upon it: I will feature the best forks in a future video :)
For other tutorials: http://vittorioromeo.info/tutorials.html - or just browse my YT channel.
Thanks for watching!
-
Well, that was basic but well explained. And I learned some things ! Like the use of "remove_if" (i never knew how to use it). I have two questions:
"constexpr" its the same than "#define" but more oriented to define variables ?
aaaand.... I don't understand how this code:
shape.setSize({paddleWidth, paddleHeight});
is equivalent to this one:
shape.setSize(Vector2f(paddleWidth, paddleHeight));
How exactly works the initialization with { } ? Mmm
-
"constexpr" its the same than "#define" but more oriented to define variables ?
No, totally not. constexpr declares a constant expression, i.e. a constant known at compile time. Integral constant expressions can, for example, be used as the size of arrays.
How exactly works the initialization with { } ? Mmm
This is called uniform initialization, there are many rules how it can be applied. And it's not 100% consistent. But in this case, you can specify the constructor arguments in order.
Feel free to search for these keywords, you'll find a lot of material on the Internet :)
-
Everything Nexus said is correct, just wanted to reiterate and show more examples.
"constexpr" its the same than "#define" but more oriented to define variables ?
constexpr int arraySize{15};
int array[arraySize]; // Valid C++11 code, arraySize is a constexpr
constexpr int getArraySize(int x) { return 15 + x; }
int array2[getArraySize(15)]; // Valid C++11, getArraySize(15) can be evaluated at compile-time
int main() {
int temp;
cin >> temp;
int array3[getArraySize(temp)]; // Unvalid code, getArraySize(temp) cannot be evaluated at compile-time
cout << getArraySize(temp) << endl; // Valid code, but getArraySize(temp) will be evaluated at run-time
}
Please correct me if my example above contains any mistake.
aaaand.... I don't understand how this code:
shape.setSize({paddleWidth, paddleHeight});
is equivalent to this one:
shape.setSize(Vector2f(paddleWidth, paddleHeight));
How exactly works the initialization with { } ? Mmm
Basically, there are occasions when the compiler can automatically "guess" the type, and it's not necessary to specify it. Example:
Vector2f getMyVector1() { return Vector2f(5.f, 5.f); }
Vector2f getMyVector2() { return {5.f, 5.f}; }
// The two functions are practically equivalent
Very interesting link: http://programmers.stackexchange.com/questions/133688/is-c11-uniform-initialization-a-replacement-for-the-old-style-syntax
-
I have now watched the video too, and I really like it! :)
It's great how you keep the code simple and short. You explain and visualize it very well, by showing the effect of each code part (and even a collision diagram).
Some remarks (most of them are just minor, your video is really good):
- The SFML game loop requires event handling with pollEvent(). Depending on the operating system, the window may freeze otherwise.
- You could also mention that in game development, it's common to have a frame time parameter passed to update(). Maybe it would be too much to actually use it in the example, but just as a sidenote...
- The getter functions such as x(), top() etc. could be const-qualified, as well as the parameters here: isIntersecting(const T1& mA, const T2& mB). Same for testCollision(const Paddle& mPaddle, Ball& mBall).
- using namespace simplifies the code in your case, but it would be good to mention its disadvantages for larger projects. Without it, it might also be a bit clearer whether a function/class belongs to SFML or the standard library. But I think it's fine in your case in order to keep the code minimal.
- The header #include <SFML/Graphics.hpp> already contains <SFML/Window.hpp>.
- constexpr is nice, but from the video it's not clear why you didn't simply use const, as the effect would have been the same. But you explained it in your last post. const int size = 43; is already a constant expression; the power of constexpr lies in functions.
By the way, your link to uniform initialization is very informative, as it shows also a lot of the drawbacks when it's overused: Ambiguity with initializer lists and other overloads, less expressive code.
-
Okay, thanks for the clarifications. Now I understand my doubts ^^
and yeah Nexus, I forgot to say that I dont like the use of "using namespace <insert lib here>"
-
I have now watched the video too, and I really like it! :)
It's great how you keep the code simple and short. You explain and visualize it very well, by showing the effect of each code part (and even a collision diagram).
Some remarks (most of them are just minor, your video is really good):
Thanks for the feedback, I'm glad you found the video interesting.
- The SFML game loop requires event handling with pollEvent(). Depending on the operating system, the window may freeze otherwise.
Totally forgot about this! I added an annotation.
- You could also mention that in game development, it's common to have a frame time parameter passed to update(). Maybe it would be too much to actually use it in the example, but just as a sidenote...
- The getter functions such as x(), top() etc. could be const-qualified, as well as the parameters here: isIntersecting(const T1& mA, const T2& mB). Same for testCollision(const Paddle& mPaddle, Ball& mBall).
I wanted to keep the video as simple as possible. I will probably improve the existing code in future videos, and I will deal with const-correctness and frame time.
- using namespace simplifies the code in your case, but it would be good to mention its disadvantages for larger projects. Without it, it might also be a bit clearer whether a function/class belongs to SFML or the standard library. But I think it's fine in your case in order to keep the code minimal.
Again, I chose to use using namespace for simplicity. I will deal with its drawbacks in future videos.
- The header #include <SFML/Graphics.hpp> already contains <SFML/Window.hpp>.
Didn't know about it, guess it doesn't hurt to include it anyway.
- constexpr is nice, but from the video it's not clear why you didn't simply use const, as the effect would have been the same. But you explained it in your last post. const int size = 43; is already a constant expression; the power of constexpr lies in functions.
True, I didn't show the "real benefits" of constexpr. I may do some "quick" videos about C++11 feature, where I show where they can be most useful.
-
Thanks to everyone for the feedback!
I've uploaded the second episode of "Dive into C++11" on my YouTube channel.
http://www.youtube.com/watch?v=tPbrWAbzyTE
Playlist: http://www.youtube.com/playlist?list=PLTEcWGdSiQenl4YRPvSqW7UPC6SiGNN7e
The video is quite long - if you want to skip to the parts you may find most interesting, here's a schedule:
0:00 - constexpr addendum
3:20 - uniform intialization syntax addendum
10:10 - 1st segment (const-correctness, noexcept, event polling)
19:40 - 2nd segment (FPS and Frametime management)
34:15 - 4th segment ("time-slicing" for consistent logic with any FPS)
45:10 - 5th segment (refactoring)
In this episode we will learn more about two previously mentioned new awesome C++11 features: "constexpr" and "uniform initialization syntax".
Most importantly, we will also deal with a very big issue that every game developer must face: FPS/frametime, and how to avoid the game from behaving differently on slower/faster machines.
In addition, we'll also briefly learn about "const-correctness" and using the "noexcept" keyword.
We will analyze the "time-slice" method to allow the game to run smoothly and consistently on every machine.
In the last code segment, we will also "refactor" our code by creating a `Game` class, making our source much easier to read and maintain.
I greatly appreciate comments and criticism, and ideas for future videos/tutorials.
Feel free to fork the game's source code at: https://github.com/SuperV1234/Tutorials
-
Ill copy and paste the same i commented in youtube:
I see the constexpr functions like "inline functions" with the only difference they can be used to declare an array because the "compile-time" feature
-
Ill copy and paste the same i commented in youtube:
I see the constexpr functions like "inline functions" with the only difference they can be used to declare an array because the "compile-time" feature
`constexpr` allows compile-time computation: I don't think the standard allows (or prohibits) simple inline non-`constexpr` functions to be computed at compile-time. It's also useful for compile-time meta-programming and stuff like tuple unpacking and tuple searches.
`inline` functions are not really comparable to `constexpr`, in my opinion. Also, `inline` functions are not only a (probably deprecated) way of suggesting compiler optimizations, but they also have the (in my opinion, very useful) feature of allowing multiple definitions of the same function, as long as the body is exactly the same. In fact, I use (abuse) `inline` functions all the time in my header-only libraries.
-
Inlining a function just removes the overhead of the function call. Inline functions, like functions, are generally evaluated at run time. The more you can evaluate at compile time the better :).
-
Also, `inline` functions are not only a (probably deprecated) way of suggesting compiler optimizations, but they also have the (in my opinion, very useful) feature of allowing multiple definitions of the same function, as long as the body is exactly the same. In fact, I use (abuse) `inline` functions all the time in my header-only libraries.
Exactly. The inline keyword required to fulfill the ODR (one definition rule) and allows function definitions in headers.
inline is only a hint to the compiler to inline the function. Don't overuse this keyword for optimizations; often, it's of advantage to define functions in .cpp files. Link-time code generation still allows them to be inlined (but automatically).
-
Again, thanks to everyone for the feedback.
I've uploaded the third episode of "Dive into C++11" on my YouTube channel.
http://www.youtube.com/watch?v=0TGp0o1KnG8
Playlist (http://www.youtube.com/playlist?list=PLTEcWGdSiQenl4YRPvSqW7UPC6SiGNN7e)
In this episode we'll take a break from game development to delve into C and C++'s memory and lifetime management. We'll talk about automatic variable lifetime, pointers in general and dynamic memory allocation.
The intended audience for this tutorial/screencast are people who have some experience with C++ in general, and who watched the previous episodes. This episode may be very interesting for those with experience with C++ who want to learn more about variable lifetime and memory management.
I greatly appreciate comments and criticism, and ideas for future videos/tutorials.
Feel free to fork/analyze the source code at: https://github.com/SuperV1234/Tutorials
-
Hi Vittorio,
thanks for the videos. Really enjoying folloing them ;)
-
Hi Vittorio,
thanks for the videos. Really enjoying folloing them ;)
Thank you!
Update: I've finished writing the source code for part 4 of the tutorial.
Since I'll be busy this week it will take a while before I start recording.
The source code is available here. (https://github.com/SuperV1234/Tutorials/tree/master/DiveIntoC%2B%2B11/4_SmartPtrs) If anyone is not currently busy, I'd really like to hear some feedback on the code before I start recording, so that the quality of the final video could improve. Thanks!
-
I've looked at part 3, and it's really nice how detailed you explain everything. Also the comments in the code are very useful.
Some remarks:
- You could use size_t for indices, to avoid conversion warnings on some compilers.
- In the NaiveVector, the condition should be if (capacity <= size) instead of if (capacity < size). Imagine the case size == 1: After writing the element size will be 2, but you don't reallocate the array, so the next time you have the invalid index access ptrToArray[2]. Likewise, the copy loop accesses an element out of range, since size > capacity. In fact, size should never be bigger than the capacity.
- Less important: It might be meaningful to reallocate at the beginning, so you only do it when necessary. I personally also find if (size >= capacity) more intuitive, since the variable you query and which you have just changed appears first.
-
I've looked at part 3, and it's really nice how detailed you explain everything. Also the comments in the code are very useful.
Some remarks:
- You could use size_t for indices, to avoid conversion warnings on some compilers.
- In the NaiveVector, the condition should be if (capacity <= size) instead of if (capacity < size). Imagine the case size == 1: After writing the element size will be 2, but you don't reallocate the array, so the next time you have the invalid index access ptrToArray[2]. Likewise, the copy loop accesses an element out of range, since size > capacity. In fact, size should never be bigger than the capacity.
- Less important: It might be meaningful to reallocate at the beginning, so you only do it when necessary. I personally also find if (size >= capacity) more intuitive, since the variable you query and which you have just changed appears first.
Thanks for the feedback. I've made the changes to code. (https://github.com/SuperV1234/Tutorials/commit/425142e5045e8f0ec31577026da0f1b139e963a0)
-
I've uploaded the fourth episode of "Dive into C++11" on my YouTube channel.
Video (http://www.youtube.com/watch?v=zMdD-s5_BIY) || Playlist (http://www.youtube.com/playlist?list=PLTEcWGdSiQenl4YRPvSqW7UPC6SiGNN7e)
After looking at C and C++'s memory and lifetime management in part 3, we'll take a brief look at C++11 smart pointers. We will learn what they are, what problem they solve, their advantages and their uses.
The intended audience for this tutorial/screencast are people who have some experience with C++ in general, and who watched the previous episodes.
This episode may be very interesting for pre-C++11 users who want to learn modern C++11 memory management, but it is also suitable for beginners.
I greatly appreciate comments and criticism, and ideas for future videos/tutorials.
Feel free to fork/analyze the source code at: https://github.com/SuperV1234/Tutorials
-
I'll resurrect the thread with a new video that game developers could find interesting:
"If I want to store entities contiguously to improve efficiency, how can I keep track of them?"
http://www.youtube.com/watch?v=_-KSlhppzNE
In the video, I show two possible ways of dealing with entity storage and management:
- Storing entities on the heap. Entities are easy to keep track of, but iteration is inefficient. Very easy implementation.
- Storing entities contiguously. Iteration is cache-friendly, however it is hard to keep track of specific instances. Complex implementation with custom handles.
Hope you find some of the concepts in the video interesting!
I'm looking forward to your feedback and to more ideas on entity management.
-
Nice video.
In my current project, I'm storing my entities in a heap (vector of unique_ptr).
Storing the entities cintiguously sounds interesting. but I'm wondering if sorting the atoms, marks etc. might turn out to be more inefficient than using a heap.
What if you don't delete the dead entities, but keep track of their index in a vector and just overwrite them, when you create new entities. That way each entity would keep its index.
-
What problem have you solved? It seems like a solution to a non-existent problem.
You are asserting that the new approach is better but I don't see any reason to believe it. I was going to call it "premature optimization" but you haven't actually optimized anything, where is the analysis that proves the new system is more efficient? All you have is a code comment that says it's better.
If you are going to optimize something, then start by taking a real problem or at the very least an abstracted version of a real problem and apply your solution there so that you can show the data reflecting the improvement.
-
Nice video.
In my current project, I'm storing my entities in a heap (vector of unique_ptr).
Storing the entities cintiguously sounds interesting. but I'm wondering if sorting the atoms, marks etc. might turn out to be more inefficient than using a heap.
What if you don't delete the dead entities, but keep track of their index in a vector and just overwrite them, when you create new entities. That way each entity would keep its index.
Thanks for the feedback.
The advantage of storing the entities contiguously is cache-friendliness, which makes iteration very efficient.
I'm already "recycling" dead entities, as I'm not deallocating/reallocating any memory. The control counter is there to make sure that recycled entities are not mistaken for the entities they were previously.
What problem have you solved? It seems like a solution to a non-existent problem.
You are asserting that the new approach is better but I don't see any reason to believe it. I was going to call it "premature optimization" but you haven't actually optimized anything, where is the analysis that proves the new system is more efficient? All you have is a code comment that says it's better.
If you are going to optimize something, then start by taking a real problem or at the very least an abstracted version of a real problem and apply your solution there so that you can show the data reflecting the improvement.
Thanks for the feedback.
It isn't a magical "solution to a problem", it's more of a different approach to entity management to increase iteration speed and still retain the possibility of tracking several entity instances.
Using a vector of unique pointers is still the easiest (and sometimes best) solution for games that do not require particular iteration efficiency.
There are many studies/, slides and benchmarks online (done by AAA game developers, as well) that show how important is cache-efficiency for game development. Just look for "data-driven design" and "cache friendliness" on google.
-
Hello everyone! I've just finished uploading the latest episode of "Dive into C++11".
http://www.youtube.com/watch?v=QAmtgvwHInM
In this episode we'll see various ways of implementing entity management in your games, starting with a very simple "one vector per object type" approach. We'll consider a "polymorphic inheritance tree" approach as well, and finish the video by re-implementing our Arkanoid clone with a simple but effective component-based design.
The goal of the episode is showing the thought process behind the design and improvement of an entity management system.
The intended audience for this tutorial/screencast are people who have some experience with C++ in general, and who watched the previous episodes. This episode also teaches the basics of polymorphism and component-based design.
Hope you'll find the video interesting!
I greatly appreciate comments and criticism, and ideas for future videos/tutorials.
-
Instead the template trick you talk about (static getID with a counter++ for each class) I use this:
// In Entity class...
std::unordered_map<std::type_index, std::list<std::weak_ptr<Component>>> mComponentArray;
So the type_index can be retrieved doing:
std::typeid(T)
... in the template methods, for example:
template <typename T>
bool Entity::HasComponent() const
{
if(mComponentArray.count(std::typeid(T)))
{
return (! mComponentArray.at(std::typeid(T)).empty());
}
return false;
}
--------------------
I store too a list in the EntityManager to get fast all entities which have a specific component attached:
// In EntityManager class ...
std::unordered_map<std::type_index, std::list<std::weak_ptr<Entity>>> mEntityComponentContainer;
template <typename T>
auto EntityManager::GetEntities() -> std::list<std::weak_ptr<Entity>>&
{
if(EntityManager::HasEntities<T>())
{
return EntityManager::mInstance->mEntityComponentContainer.at(std::typeid(T));
}
return EntityManager::mInstance->mEntityComponentContainer[std::typeid(T)];
}
then it can be used for example with this:
template <typename T>
void EntityManager::ForEach(const function<void(std::weak_ptr<Entity>)> function)
{
for(auto& iEntity : GetEntities<T>())
{
function(iEntity);
}
}
-
It will certainly work, but it seems unnecessarily inefficient and complex.
`std::typeid` and an `std::unordered_map` have a significant runtime overhead. Also, you cannot use `noexcept` to allow even more aggressive compiler optimizations.
I don't think it can get much faster than a bitset lookup for component availability checks and a direct array access to retrieve a component of a specific type.
A possibly even more efficient version could use a variadic list of component types passed in the manager (which would be a template class) so that appropriate data structures and unique IDs could be generated at compile-time. But I don't think it would be much faster than the implementation I show in the video.
I'm also a little perplexed by the use of `std::list` (which is highly not recommended by Bjarne itself, because of its cache unfriendliness), `std::weak_ptr` (wouldn't a raw pointer do the trick here?) and `std::function`, which, again, has some runtime overhead.
Instead of passing an `std::function` to `EntityManager::ForEach` you can simply add and use a template parameter for the passed function type, which will have no runtime overhead.
Your design and implementation is probably fine for any kind of game that has a small amount of entities... but I really like to make my life harder by trying to squeeze every last bit of performance in my code.
It feels rewarding and I always learn unexpected things about efficient code :)
-
Wtf, I thought my code had at least some optimization but okay....
Anyway, I'm focused in FINISH something, optimization can be done later ... I appreciate the comments though ;D
I think the article you mean when said "std::list (which is highly not recommended by Bjarne itself)" is this one, so here is the link: http://isocpp.org/blog/2014/06/stroustrup-lists
Maybe i'll optimize the std::function part ... I'm pretty sure they are slow
-
I'm not sure if you meantioned it in your handle-video(didn't have time to watch it yet), but it should be noted that the std::aligned_storage_t Helper type and many more features(like return type deduction without a trailing return type specifier) are only available since C++14.
If you already mentioned it in your video then nevermind.
Last but not least(really nitpicking):
You should use the uniform_int_distribution for uniform random numbers. The modulo 50 operation generates slightly biased values, which should not be what anyone wants :D
-
Dammm.... okay I replaced all the lists (I had only 3, but okay), and replaced all weak_ptr by raw pointers (but still using shared_ptr to allow RAII and clear ownership).
There's a good replacement for the unordered_map containers (I use them a lot) ? Anyway I really dont think they are too bad in perfomance/memory ...
Btw ! I forgot to say that in my implementation I allow the creation of TWO or more components of the same type for an entity (thats why I use an unordered_map with a list [now a vector] of components for the second type). How would be in your bitset implementation ?
-
I really like your YouTube series!
I recently started again developing in C++ (I usually use C# for work) and your tutorials helped me a lot. ;)
I have 2 questions:
1) In Episode 2 (about Frametime and FPS) is there a benefit using std::chrono instead of sf::Time? I am researching about Game Loop and Game Time and I am still trying to find the best approach. BTW I really liked the Fixed time slice approach.
2) Based on Episode 5 (Game entity management basics) I wanted to make a space invaders clone.
I expanded the p9.cpp and created my game. The problem is that I haven't figured out how to create Entities in real time. For example when player presses the space bar, a bullets gets fired from player ship. (Maybe I need to brush up my C++ skills :-[)
Thanks in advance!
-
Your tutorials are still very good. I like the way you describe the ECS and visualize it with comments and ASCII art in code. The verbosity of comments allows to pause the video and makes the code really clear! :)
A few comments about video 5, again just minor issues:
- Base classes that aren't instantiated should be abstract, corresponding virtual member functions pure.
- You could show std::make_unique() (C++14). emplace_back() with raw new is not exception-safe (http://stackoverflow.com/q/13172888), leading to possible memory leaks. In general, I would avoid new where possible -- especially if you wrap the pointer in a smart pointer anyway.
- It's a matter of style, but I personally mark virtual methods always with the virtual keyword (even if there is override)
- Calling a parameter mArgs is rather unusual; the "m" prefix is commonly used for members.
- You mix uniform initialization {} with constructor-style parentheses () for no apparent reason. Same with different integer types in the same loop... Both around 20min in the video.
- You use both abs() and std::abs(), the latter is correct.
-
Thanks everyone for the feedback!
1) In Episode 2 (about Frametime and FPS) is there a benefit using std::chrono instead of sf::Time? I am researching about Game Loop and Game Time and I am still trying to find the best approach. BTW I really liked the Fixed time slice approach.
I don't think there is a particular benefit - I was trying to be as standard-compliant as possible and use modern STL features.
2) Based on Episode 5 (Game entity management basics) I wanted to make a space invaders clone.
I expanded the p9.cpp and created my game. The problem is that I haven't figured out how to create Entities in real time. For example when player presses the space bar, a bullets gets fired from player ship. (Maybe I need to brush up my C++ skills :-[)
Create a function similar to `createBrick` and call it during your game loop - you can do it after spacebar is pressed, for example.
- Base classes that aren't instantiated should be abstract, corresponding virtual member functions pure.
Classes that derive from abstract classes explicitly require to define the base class's abstract methods.
In my design, components can often have an empty `draw` or `update` implementation - forcing the derived type to implement an empty version of those methods is not something I want to do.
- You could show std::make_unique() (C++14). emplace_back() with raw new
is not exception-safe (http://stackoverflow.com/q/13172888), leading to possible memory leaks. In general, I would avoid new where possible -- especially if you wrap the pointer in a smart pointer anyway.
This is correct - the `new` keyword should never be used (unless we're using "placement new").
Unfortunately the video is targeting the C++11 standard, so I can't use `std::make_unique` in it.
- Calling a parameter mArgs is rather unusual; the "m" prefix is commonly used for members.
I've received the same feedback on my naming conventions before, and you're probably right - "m" could seem an abbreviation for "member".
The truth is that I'm really really used to this naming convention so it would take a lot of time and "find-replace regexes" to change it - I'll think about it.
- You use both abs() and std::abs(), the latter is correct.
Correct, will fix this as well in the GitHub code.
-
The link doesn't seem to work. It comes up with a 404 this is not the page you are looking for.
-
The link doesn't seem to work. It comes up with a 404 this is not the page you are looking for.
What link?
-
Hi Vittorio,
thanks for the videos. Really enjoying folloing them ;)
Thank you!
Update: I've finished writing the source code for part 4 of the tutorial.
Since I'll be busy this week it will take a while before I start recording.
The source code is available here. (https://github.com/SuperV1234/Tutorials/tree/master/4_SmartPtrs) If anyone is not currently busy, I'd really like to hear some feedback on the code before I start recording, so that the quality of the final video could improve. Thanks!
This one. Sorry, I must have clicked on the wrong page.
-
Hi Vittorio,
thanks for the videos. Really enjoying folloing them ;)
Thank you!
Update: I've finished writing the source code for part 4 of the tutorial.
Since I'll be busy this week it will take a while before I start recording.
The source code is available here. (https://github.com/SuperV1234/Tutorials/tree/master/4_SmartPtrs) If anyone is not currently busy, I'd really like to hear some feedback on the code before I start recording, so that the quality of the final video could improve. Thanks!
This one. Sorry, I must have clicked on the wrong page.
Whoops - you're right. I've moved stuff around in the repository.
You can find "4_SmartPtrs" here:
https://github.com/SuperV1234/Tutorials/tree/master/DiveIntoC%2B%2B11
-
I've published two new video tutorials on my YouTube channel.
The videos introduce a new series: "Dive into C++14".
Like the previous series, dedicated to the C++11 standard, "Dive into C++14" will show the convenience and power of the latest standard (C++14) through videos regarding various topics.
The format of the videos is what makes "Dive into C++11" and "Dive into C++14" different from other tutorials: well-commented and well-formatted independently compilable chronologically sequential code segments will show the audience the thought process behind writing modern C++14 code.
The first two videos are not really related to game development, but I find myself using the features/patterns described in them a lot for my game projects, so I hope they're not out-of-scope for the SFML forum.
* Dive into C++14 - [1] - Introduction to C++14 core language features
http://www.youtube.com/watch?v=WZYKzCsACiw
The first video is a brief introduction to some of my favorite new C++14 core language features.
It covers the following topics, using code examples:
* Function return type deduction.
* `decltype(auto)`.
* Relaxed constexpr restrictions.
* Variable templates.
* Generic lambdas.
The target audience is newcomers to the C++14 standard who already have some experience with C++11.
* Dive into C++14 - [2] - `for_each_argument` explained and expanded
http://www.youtube.com/watch?v=Za92Tz_g0zQ
The second video covers a very interesting code snippet originally posted on Twitter by Sean Parent: `for_each_argument`.
It shows and explains the usage of C++14 compile-time integer sequences, and analyzes a very interesting iterative implementation of an alternative version of Sean's function that takes the desired arity as a template parameter.
This tutorial video is a reviewed and improved version of my C++Now 2015 lightning talk ("`for_each_arg` explained and expanded").
Some possible use cases for the implemented functions are also shown and analyzed:
* `make_vector(...)`
* `forTuple` - iteration over tuple elements
* `make_unordered_map(...)`
The target audience is people with knowledge of C++11 features and some C++14 experience.
I greatly appreciate comments and criticism, and ideas for future videos/tutorials.
Feel free to fork/analyze/improve the source code at:
https://github.com/SuperV1234/Tutorials
You can find previous episodes here:
https://www.youtube.com/playlist?list=PLTEcWGdSiQenl4YRPvSqW7UPC6SiGNN7e