-
Greetings!
I am happy to announce that the first SFML book has just been released! Nexus, Groogy and I have put a lot of work and dedication into this book along the last semester and, now it's ready, we can only sincerely hope you enjoy the book to the fullest.
SFML Game Development is highly focused on using C++11 with SFML in a modern way, in order to create an up-to-date learning experience, where you can get information all the way from the basics until building an actual game!
You can purchase either a digital copy or an actual hard cover book in the following website:
http://www.packtpub.com/sfml-game-development/book
The source code can be downloaded from the PacktPub website as well.
The sample game we produced for the book is all about airplanes and bullets in the sky! You are engaged in a modest warfare where you can kill enemy units and progress through a level until you are victorious. Along these gameplay elements goes a set of sounds that give life to the game and some interesting graphic effects such as bloom. A network mode is also present, showing you how you can interact with friends in co-op and online gameplay.
The following screenshot was taken directly from the sample game:
(http://i.imgur.com/kiQ6KXY.png)
This book was written in a way where the text evolves in parallel with the code, meaning that for each chapter you will have source code relating only to what was written so far, progressing through the chapters until a finished game is obtained!
Also, a special thanks to Laurent for his support through every stage of development, as well as his feedback whenever we needed!
We really hope everything is of your taste and we honestly appreciate any feedback you can give us!
Regards,
The team
-
Hi,
First I must congratz the whole team : authors, editors and Laurent.
I already started it, I'll spoil evryone that Harry dies in the end. Oh, wrong book...
I'll make more feedback as soon as I finished it !
Thanks a lot a lot a lot !
-
Amazing! Congratulation, all of you! :D I'll buy it at Fnac and will ask the guy to order 3 or 4 more for other people. Of course, I'll take care to put them on the front during my next visit ;)
-
Been reading parts of the ebook since this morning. Seems really great and I hope to learn some new stuff on topics I'm not experienced in! ;)
I'm also looking forward to diving into the nice C++11 style and of course the hard copy.
Congrats again to all three authors and special thanks to Laurent for his constant support.
-
Looking really nice judging from the preview on Amazon! Sadly my credit card is having problems this evening so I'll give it a shot when I'm less tired tomorrow - can't wait to read it!
-
Looks really good, I plan on ordering a hard copy tomorrow ;D
-
Congrats on getting it out!
I'll be sure to get myself a copy as well. :)
-
Congrats to everyone I will be ordering it with in the week (:
-
Is this book beginner-only or do you think people who have some experience with SFML2 could benefit from it as well?
-
Thanks everyone for the support! It feels great to know you're curious about the book :)
Even if you aren't a beginner anymore, it is likely you will find a few topics you don't know a lot of yet and will benefit you in some way. Also, our specific implementations of many things within a game might be of your interest and perhaps introduce you to new approaches, which might be a good addition to your knowledge.
:)
-
Thanks everyone for the support! It feels great to know you're curious about the book :)
Even if you aren't a beginner anymore, it is likely you will find a few topics you don't know a lot of yet and will benefit you in some way. Also, our specific implementations of many things within a game might be of your interest and perhaps introduce you to new approaches, which might be a good addition to your knowledge.
:)
Bought!
-
Is this book beginner-only or do you think people who have some experience with SFML2 could benefit from it as well?
To expand upon what Grimshaw said, we introduce a general-purpose command/message system in the book which even for some non-beginners could be a new thing to learn. Also we cover a lot of advanced topics like particles, post processing and network which you might not have learned either yet.
Also thanks for the appreciation here on the forum :)
-
Hi, I bought this book today and I really like it!
However, I can't seem to download the files which belong to the book from the PacktPub website: Once I select the book on the PacktPub support site (http://www.packtpub.com/support/12705) I can only see a message telling me: "There are no support files for this title." :-\
-
One of the authors said on the french forum (http://fr.sfml-dev.org/forums/index.php?topic=11993.msg83330#msg83330) that the publisher informed them that they are in the process of uploading the files.
-
Okay, thanks for the information.
-
Yes, I'm not entirely sure when they will be finished uploading it, but I expect it to happen soon! :)
-
Congrats guys! Just purchased and checking it out. :) I only wonder how the cover is related to SFML?! :P
-
Thanks Tank! All Packt book covers seem to be random photographs.. I'm not sure why but I guess we could be worse hehe :)
-
Indeed, especially considering the fact that the content counts. ;)
-
The sourcefiles are uploaded by now. However i have some problems to get everything running. Using Visual Studio 2012 Chapter 1-6 compile without errors. But the other ones give me the following error message:
Error 6 error C3849: function-style call on an expression of type 'const std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>' would lose const and/or volatile qualifiers for all 2 available operator overloads SFML Game Development\07_Gameplay\Include\Book\Command.hpp
Any suggestions? Im not that experienced and would appreciate your help.
-
Congrats guys! Just purchased and checking it out. :) I only wonder how the cover is related to SFML?! :P
Thanks :)
THe cover is pretty normal for technical books, it's either something like this or pointless vector graphics. Got ton of programming books where none have a cover related to the actual topic. I mean the mythical man month book got dinosaurs on it's cover ;)
The sourcefiles are uploaded by now. However i have some problems to get everything running. Using Visual Studio 2012 Chapter 1-6 compile without errors. But the other ones give me the following error message:
Error 6 error C3849: function-style call on an expression of type 'const std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>' would lose const and/or volatile qualifiers for all 2 available operator overloads SFML Game Development\07_Gameplay\Include\Book\Command.hpp
Any suggestions? Im not that experienced and would appreciate your help.
We only used VS10, MinGW and Linux environments when developing. We're having a look at Visual Studio 2012 now to correct the problem.
-
Bought the book from Amazon UK yesterday but the source files are still unavailable from the website. Is the download perhaps location dependant?
-
Bought the book from Amazon UK yesterday but the source files are still unavailable from the website. Is the download perhaps location dependant?
You should be capable of downloading it from here: http://www.packtpub.com/support/12705
I don't think that Amazon provides their own source of download I am afraid.
-
Thats where I have been trying but it doesnt have any place to put in my email address to provide the link to the code even though its available for other books and seemingly other people. Weird but I will keep trying. The book is excellent, good to see C++11 being used as well.
-
Thats where I have been trying but it doesnt have any place to put in my email address to provide the link to the code even though its available for other books and seemingly other people. Weird but I will keep trying. The book is excellent, good to see C++11 being used as well.
Thanks, Nexus will be happy, he was the one suggesting that we should use C++11, and I'm happy we went that direction. The modern programming style we use makes the book in my opinion.
Regarding the download, contact Packt Support, could be that you have to register the book at Packt since you bought it at a third party.
-
Yeah ill do that, thanks :)
As someone who has just updated a massive project in work to c++11 I agree that it is far better and code looks much tidier and runs faster. Good work guys :)
-
Can't wait, my copy arrives tomorrow :D
Thats where I have been trying but it doesnt have any place to put in my email address
The email option is there now, Packt must have just updated it.
-
So just to clarify, if I buy the book from amazon, will I have access to the code from Packt? It looks good, great job :).
-
So just to clarify, if I buy the book from amazon, will I have access to the code from Packt? It looks good, great job :).
Yes you will. You get a download link from their support page.
Also the compile problems with VS11 is bugs that has been introduced in the new compiler, no ETA on when they will fix it. So I have done some fixes in the source code, will get it uploaded as soon as possible.
Bug issue: http://connect.microsoft.com/VisualStudio/feedback/details/773565/cannot-call-const-forwarding-call-wrapper-result-of-std-bind
-
Hi. If I purchase the book from Amazon, will I get the "free eBook + free PacktLib access" to the book? :)
-
I purchased the eBook Kindle thing from Amazon. Its really good by the way. When you get the kindle version you can just put you email in at http://www.packtpub.com/support/12705 and you will get all the code emailed to you. You don't have to prove that you bought the book. Just put in your email, don't get their newsletter, and then enter the catch-pa. Once you hit the "go" button to the left of the catch-pa field, you will get an email within minutes with the downloadable code.
Once again, I've barely started the book but I'm loving it! :)
-
*throws $$ at screen* Just take it all, HERE! So I was him-hawin' about buying this and before I knew what was happening my debit card was out and now I have a print copy coming and am reading a digital copy. I've enjoyed what I've read so far.
-
Note that you can download source code without buying the book.
-
Wow, nice work guys!
Oh, does it explain how to create the structure of your game? Like how to handle inputs, render, update...
Thanks!
-
Yes! It explains all those basics in chapter one, and then you have nine left :D
-
Also from my side, thanks a lot for all the positive feedback! Really glad you like the book :)
Artfloriani, yes that's the focus of our book (besides teaching SFML): it shows a possible code design for your game. We often discuss the decisions we make and explain their advantages or disadvantages. The first chapter contains an introduction to SFML and game basics. The further chapters explain parts of the game architecture in detail, for example resource management, input handling, world/entity organization, menus, audio, ...
-
Ok!
Thanks a lot, I loved the ebook concept.
-
So does this book get everyones' blessings then? With the price the ebook is at I'll definitely end up buying it at some point if it's all 2.0 code.
-
Bought the book. Thanks for writing it. I cannot find any of the source files, but I guess from other topics it's clear that they are in process of being uploaded?
-
I got it directly from Packtpub and on the left hand side of my completed transaction screen were the links to download the ebook and a download link for the source files, maybe you just missed the link? Or if you bought through Amazon or somewhere else you gotta link your order to packts site or something.
-
See a few pages earlier, someone provided the link, you can even get source without having bought the book/ebook.
So does this book get everyones' blessings then? With the price the ebook is at I'll definitely end up buying it at some point if it's all 2.0 code.
Yes, go for it. ;)
-
As I said on the French forums, I've read about 70% of the book and even if I already knew a lot of things inside it, I learned a lot others as well. My favorite part is how the entities communicate with the "command" element, that is a part that I always missed in my previous games.
I learned a lot about SFML/OpenGL as well and that is really a good thing.
I'm looking forward to go through the network part, that should be very interesting =)
I've read a lot of books about how to make a video game before. That is the one I prefer. It's clear, there are a lot of examples, if you don't get a part at first read, you get it at second, the examples are linked together and the final (game) goal is well defined. Perhaps my past exeperiences with SFML help me in understanding it, but it doesn't remove the clarity the authors manage to have.
Authors, the more I read the more I love you !
-
See a few pages earlier, someone provided the link, you can even get source without having bought the book/ebook.
So does this book get everyones' blessings then? With the price the ebook is at I'll definitely end up buying it at some point if it's all 2.0 code.
Yes, go for it. ;)
SOE and EA shall fear my wrath! BWHAHHAHAHAHHAAAAA!
-
Was very happy to see this mentioned on the main SFML page -- went ahead and bought it; looks like exactly what I'm looking for.
Very excited to read, and congratulations on the release!
[EDIT] Reading the PDF (which is great Packt included with my hard copy book... head start! :D)... so far... fantastic! Work tomorrow (I guess today already since I am now in the AM's :P) is going to come to a crawl because I will be so eager to continue reading this =]].
-
Just bought it and I'm reading through it now, it looks very promising, also, thank you for not being a complete bastard and putting DRM all over the .pdf file so I can store it and keep it offline. Too often I buy something digital only to discover if the internet goes down I can't even use it properly.
More developers just need to say no to DRM that doesn't even work.
Edit: The best thing about this book is on one of the very first sections it goes into a lot of detail about a problem I posted on these boards which is really nice :D
-
Just bought it and I'm reading through it now, it looks very promising, also, thank you for not being a complete bastard and putting DRM all over the .pdf file so I can store it and keep it offline. Too often I buy something digital only to discover if the internet goes down I can't even use it properly.
More developers just need to say no to DRM that doesn't even work.
Edit: The best thing about this book is on one of the very first sections it goes into a lot of detail about a problem I posted on these boards which is really nice :D
Ah that, we have no control over. That's the publisher that needs cudos for not being dicks then ;)
-
lol! If it's the publisher indeed! Normally they're the ones responsible for DRM at all.
-
Congrats for the book! Looks like I'll be able to get it from the publisher for review. If not I'll buy it anyway! :D
-
just bought the ebook version! Hoping to learn alot. Thanks
-
Okay, there are huge changes in SceneNode (about Categories and update that takes CommandQueue, mainly) between chapters 6 and 7 that you do not speak about.
It took me some time to figure out why there was 6 bullets shot instead of one, that's because the Layer and Categories attribution has changed in World class.
-
Thanks for the feedback! Of course, we cannot address every change in the code, since it's just too much. But if we missed something important, we would like to know :)
Concerning the signature that changes from
void SceneNode::update(sf::Time dt)
to
void SceneNode::update(sf::Time dt, CommandQueue& commands)
The signature is extended because commands are incorporated into game logic. In Chapter 4, commands were introduced, but only used for input handling. At the end, we mention that the command system can also be used for other things like network input or in-game events. But you're right, we should probably have mentioned it again (and more clearly) in Chapter 7.
There are never 6 bullets shot at once, but at most 3 (namely when the player collects the pickup twice). This is explained:
You may notice that the player's Eagle plane shoots two bullets at once, which is the result of a previously collected fire spread pickup.
-
There are never 6 bullets shot at once, but at most 3 (namely when the player collects the pickup twice). This is explained:
You may notice that the player's Eagle plane shoots two bullets at once, which is the result of a previously collected fire spread pickup.
No, you misunderstood me (or I wasn't clear enough) :
The fact that you added that code into World::buildScene() [without telling the reader] :
Category::Type category = (i == Air) ? Category::SceneAirLayer : Category::None;
Changes the behavior for bullet shot. In fact it solves a problem. Indeed, before that line was added every SceneNode had a category Category::Scene. That is the category for the Projectile firing Command too.
But : or you didn't mention that change in the book or I totally missed it, so every SceneNode still has the Category::Scene category in reader code (SceneNodes that have not overloaded the getCategory() method, of course).
The result is that the bullet firing event is "catched" by 5 or 6 SceneNodes that are in Scene category. Each of them will action the command, giving a different "parent" node to the bullet.
Concerning the signature change for update() method, you didn't mention it in the book but it was clear (for me, at least). Perhaps a fast mention can help some people, dunno.
-
I see this might be a bit confusing. To clarify:
- The layer nodes that we need to differentiate (for game logics) have their own category, here SceneAirLayer.
- Those that never receive any commands have category None.
- Generic scene nodes which aren't explicitly assigned a category have category Scene.
The bullet firing event is addressed to Category::SceneAirLayer, which is held by only one scene node in the whole graph. Therefore, it is only attached to a single node, not 6.
Don't worry too much about None and Scene, they are not important. It is good if you understand the idea behind categories, and see the differences between the gameplay-related categories, such as EnemyAircraft ;)
-
Ok, so next step is to add "Let There Be Light" (and then Box2d) with the system. I'll do it, I'll do it ...!
-
Does anyone know what licence the source code in this book was released under? I'd like to push my implementation of the game to a public repository as I read the book. Don't want to violate copyright. Thanks :)
-
We already asked the publisher concerning the source code license, but we haven't received an answer yet. I'll write them again.
-
Page 77 in the book gives the code for your World constructor, but the very top line of it is omitted. It's missing "World::World(sf::RenderWindow& window)"
ALSO the same page the line that sets mSpawnPosition is missing " .y / 2.f " at the end of the line.
Printed:
, mSpawnPosition(
mWorldView.getSize().x / 2.f,
mWorldBounds.height - mWorldView.getSize()
Should be:
, mSpawnPosition(
mWorldView.getSize().x / 2.f,
mWorldBounds.height - mWorldView.getSize().y / 2.f
-
Ok, thanks. It looks like there is even more missing.
This specific code snippet was (wrongly) reformatted in the very last phase, thus we had to describe what's wrong and couldn't edit it ourselves anymore. Apparently, the description was not correctly interpreted.
The correct snippet is:
World::World(sf::RenderWindow& window)
: mWindow(window)
, mWorldView(window.getDefaultView())
, mWorldBounds(
0.f, // left X position
0.f, // top Y position
mWorldView.getSize().x, // width
2000.f) // height
, mSpawnPosition(
mWorldView.getSize().x / 2.f, // X
mWorldBounds.height - mWorldView.getSize().y / 2.f) // Y
, mScrollSpeed(-50.f)
, mPlayerAircraft(nullptr)
{
loadTextures();
buildScene();
mWorldView.setCenter(mSpawnPosition);
}
-
I have purchased the SFML Game Development book from Amazon UK (as directed by packtpub) and I attempted to find some way of linking the purchase with my PacktPub account (freshly created).
This is of course in order to acquire access to the e-book, which I haven't had any luck in pulling off thus far. The price for the print version however is equal to that on packtpub from amazon uk, and therefore I assume it will grant me the ebook version as well.
I'll keep you updated on how this turns out, unless someone has already found a solution to it, in which case I urge you to post it for my benefit and anyone else who might require it =]
-
This is by far one of the more impressive books I have read on programming so congrats on that :D. I honestly did not manage to understand the uses of some of C++11's new features until reading this.I really like how the chapters flow together so you can develop one project throughout the lessons.
-
Bought this book at the weekend, really enjoying it so far. A chapter on box2d would be great for the next version :)
-
Bought this book at the weekend, really enjoying it so far. A chapter on box2d would be great for the next version :)
I agree :p
-
This is amazing, I love seeing how far SFML has progressed since I first heard of this. Getting the book asap
EDIT Q: If i order this on amazon am I also able to grab an e-book of it? I enjoy amazon shipping ;D
-
I recently bought the book and am pretty happy with it. Everything is detailed nicely and it explains it throughly as you go along. Overall I'd highly reccommend this book.
-
Look what I got today! :)
(http://i.imgur.com/w2jgDd4.jpg)
-
Awesome! <3
From the whole team, thanks for the support and all the bug reports we have gotten :)
Will be putting out a public repository for the code pretty soon, we are still trying to choose a fitting license.
-
Hiya. I started reading the PDF/eBook, and I have to say; I'm slightly disappointed.
Even on the first few pages, I found grammar and spelling mistakes that really told me that Packt didn't even try to correct the book. Books take a long time to write, and a lot of care, and I know this.
Before you start telling me I'm some useless kid who doesn't know what they're talking about, I'll quickly state my position; I'm #sfml's grammar Nazi, and I'm taking part in the IB diploma program, mainly focusing on English, which happens to be my first language.
Writing a book with multiple people is almost as difficult as trying to write software with a C++ developer, a C developer, and a Java developer combined, in Perl. It's possible, but chances are, you'll get mixed up and disagree on a lot of things. And that's exactly how it felt reading this book. I could tell exactly who wrote what, even with my little experience on this forum, because you all write in different ways, and have different approaches to solving problems, which is obviously a Human trait.
Where things went wrong, is that, as far as I know - and this isn't an insult or anything - all of the authors are ESL (English Second Language), and each are coming from different languages, which often leads to expressions being "borrowed" from said "Mother Tongue" to English. Another thing that Packt should have proofread.
It hurts me to blame the authors, but I can't blame the publisher for not re-writing the whole book. Upon reading the first paragraph (and it took me a lot of scrolling to get there, author descriptions and all that go at the end of the book), I wanted to stop reading. The book seemed like a wall, it was slang, but it was menacing, I didn't feel invited to continue reading. The introduction felt more like a conclusion, it didn't feel thought-out.
As a side-note, It would have been nice if they had indented the paragraphs, for the sake of readability. And syntax highlighting would have been great, too.
Another thing that irks me is the obvious amount of effort that was put into it. Books are hard work, and writing a 300-page book in 6 months is obviously going to lead to mistakes and whatnot. You used "we" in a way that really only included yourself. You're constantly missing verbs in sentences because you write the way you were to speak. The titles weren't centered either, and their names were slightly ridiculous. You all had different coding styles, different indenting in code, and even that irked me.
You all seemed so focused on finishing the book according to the deadline that you didn't pay attention to producing a quality book, and working like that is good for a forum post, a text message, an e-mail to your coworker, but not a book.
I guess what I mean is, it's not easy to write a book, and don't write books like forum posts.
-
I disagree with you about so many points.
Yes english is not their mother tongue (neither it's mine), as well as many other programming book writers. You can't blame them for bad expression translations or few grammar mistakes.
In my point of view, every expression was understandable.
I don't think authors disagree in the book. I really do not know how they proceeded, but I felt that they did the whole project all together and then divided the writing between each other. Of course we feel who's writing what chapter, but that's perhaps because I'm used to read forum posts from authors or because I know, for example, that an author already had that project including that functionality the chapter is talking about.
About identation it's diffenrent between my Kindle and the real book, perhaps it's the same for you, dunno.
Unlike you I really was in the book, it was difficult to dettach myself from it. I think that point is only a matter of point of view, each reader is different.
I do liked the way they wrote the book. Perhaps they wrote it a bit like they speak, but since english isn't my first tongue that makes easier for me to understand it. When I want to read "real" english I just take a litterature book.
My point is that the book isn't only aimed to english and american guys. There's a lot of people around the world that were waiting for it. There are probably less english mother tongue people around here than english second language people. I think you're a bit hard. That's also good to point out grammar mistakes for future corrections.
Be happy a common french guy haven't written it, we're (in average) very bad in english and I think you've seen that in my post (sorry !).
-
Yes english is not their mother tongue (neither it's mine), as well as many other programming book writers. You can't blame them for bad expression translations or few grammar mistakes.
In my point of view, every expression was understandable.
There weren't a few, there were many mistakes. It's Packt's job to correct such mistakes, but it's also the authors' job not to make such mistakes.
I don't think authors disagree in the book. I really do not know how they proceeded, but I felt that they did the whole project all together and then divided the writing between each other. Of course we feel who's writing what chapter, but that's perhaps because I'm used to read forum posts from authors or because I know, for example, that an author already had that project including that functionality the chapter is talking about.
I didn't say they disagreed, they had very different writing and coding styles, and sometimes following a sort of "mini standard" can be important.
Unlike you I really was in the book, it was difficult to dettach myself from it. I think that point is only a matter of point of view, each reader is different.
I do liked the way they wrote the book. Perhaps they wrote it a bit like they speak, but since english isn't my first tongue that makes easier for me to understand it. When I want to read "real" english I just take a litterature book.
Perhaps as someone who has English as a first language, I notice these issues more than someone who is ESL, but they're still present, and Packt is a English/Indian publisher.
My point is that the book isn't only aimed to english and american guys. There's a lot of people around the world that were waiting for it. There are probably less english mother tongue people around here than english second language people. I think you're a bit hard. That's also good to point out grammar mistakes for future corrections.
I don't categorize the designated audience by nationality, but rather by language. I'm of course aware that there are more ESL people on this forum than otherwise, but for all languages, books written for adults should always be accompanied with an academic level of said language, because that kind of language is what people will speak later on.
Be happy a common french guy haven't written it, we're (in average) very bad in english and I think you've seen that in my post (sorry !).
I'm Belgian, living near the French border, I'm aware of some people's English levels around here. ;)
-
(and it took me a lot of scrolling to get there, author descriptions and all that go at the end of the book)
Well no. I have tons of programming books and none put the author description at the end, only a shorter one at the back. The reasons is that you want to see if the author is supposed to be an expert in the domain before even considering the book.
As you said you scrolled, I think you used the epub or even pdf version which when read in, say, a Sony Reader or iPad, will begin at the very first page, while if you use the mobi version with a Kindle, you open the book directly to the beginning of the book. It's mostly a packaging issue or a format desing issue or a reader implementation issue.
Whatever, my point is when I received the access and open the book on a Kindle, my first reflex was to go back to check the authors description (I don't know a lot about people around here).
Note that with paper you jump faster to whatever you want.
-
Did someone accidentally change the extension when they uploaded the source code? I downloaded it and it says .zip.htm so when I open it it buggers up and goes to waterfox then loads lots.
Edit: Oh wait lol for some reason my computer defaulted to waterfox by default, I changed to winrar and it works fine now.
-
I picked up a copy of the book and so far it's been an frustrating experience for various reasons and I'm only Chapter 2...
In Chapter 1 you list the update() method which a little futher on you modify to include delta time. Confusingly but the latter code listing has introduced a 'PlayerSpeed' variable which left me wondering if it was relevant for the new functionality, it wasn't so why was it changed?
Chapter 2 doesn't build on what was just built in Chapter 1. The demo code in the download makes no use of the 'Game' class at all, why not ? I thought the idea was to progressively build a top-down shooter ?
I really hope it get's better, as it is now I wouldn't recommend it.
James
-
So, I'm up to chapter 5 now though my own personal opinion is that this book is pretty awesome, I can see where others are having frustrations with it. From what I've taken away from this book so far is that it isn't for absolute beginners. This book doesn't hold your hand by having you type 'xxx' on line 7, then 'yyyy' on line 8 and 'zzzz' on line 9. Instead it kinda hits on the major ideas presented in the chapter with showing code for the meat&potatoes part of the programs. Usually I read through a chapter, load up the finished source code for said chapter, read through the code, look at the parts that are explained in the chapters and incorporate what isn't talked about myself into my own code.
I agree that it could have been written a bit better, maybe with having each chapter contain a section that lists each file that will be created or edited in the current chapter. There are a few times the authors start writing about idea and throwing functions and methods out only to in a section later finally say that these function belong in 'Whatever.hpp" file. I find rewriting the code from the source to my own project is far stronger for my own personal learning methods than just being told to write this, then that, then this, then that. When I don't understand a chunk of code I refer back to the chapter and reread the ideas presented and then it usually sticks.
So far I give the book an 8/10 on content but a 4-5/10 on execution.
-
Thanks for the feedback! :)
Confusingly but the latter code listing has introduced a 'PlayerSpeed' variable which left me wondering if it was relevant for the new functionality, it wasn't so why was it changed?
It is relevant, because we take into account the elapsed time and multiply it with the player speed. Before we just had the constant 1. The idea of this approach was to introduce delta times and show how they can be used for a frame-independent timing.
Chapter 2 doesn't build on what was just built in Chapter 1. The demo code in the download makes no use of the 'Game' class at all, why not ? I thought the idea was to progressively build a top-down shooter ?
Many functionalities are modular. First we define them on their own, later we incorporate them into the game. Don't worry, resources will be used in Chapter 3 ;)
I agree that it could have been written a bit better, maybe with having each chapter contain a section that lists each file that will be created or edited in the current chapter.
Okay. Maybe this shouldn't be part of the book (it's probably rather annoying to have a list of files at the beginning of every chapter), but rather of the code base, like some kind of a changelist between subsequent chapters.
There are a few times the authors start writing about idea and throwing functions and methods out only to in a section later finally say that these function belong in 'Whatever.hpp" file.
We could have mentioned the corresponding file more often, but we felt it isn't necessary, because mostly the file name is implied by the class name. Otherwise, we tried to mention it (but since the file is less important than the functionality itself, it may appear later in the text).
-
Hi there,
I would like to integrate Box2D with the "engine" (I really need to find another word) that you make us do in the book. I'm not a Box2D expert but I already used it and have some notions. Still I don't really see how to do it to be nice-coding stuff...
What I was thinking about :
- Add the b2world object to our World, making it iterating for collision in update() method
- Add a b2body to SceneNode or perhaps to Entity ?
- I don't really know how to handle shapes and fixtures, nor joints
- Edit: oh yeah, and I wonder about the best way to link World(+b2world) to our Entities/Bodies (should be deduced by the rest of the architecture, I guess)
Is it a good start ? Do you have ideas or leads for things that are missing ?
In parallel I think about adding a LUA SceneNode that's able to launch a script when triggered by some events. I did added LUA to my projects before and creating a SceneNode is easy so that shouldn't be a problem, I'll keep in tuch peope around here that would like to do it too as soon as it's done.
-
For as far as I've read it, I like it. English is not my main language too, but I could easily understand it. I didn't see much mistakes, probably because I just read over them or they were too minor.
I think a lot of the negative things said already are true, but irrelevant. This book isn't about teaching you perfect English, but about teaching you how to create a game using C++.
Also, I don't think this book is only good for adults. The practical way of the book is pretty good and most non-adults like me don't like too much information that looks irrelevant at first sight.
By the way, how far are you with letting it work with VS 2012? Oracle VirtualBox crashed with LMDE when I tried to play the example already...
-
Lo-X: Generally, you can link the physical objects to their scene node counterparts, e.g. Aircraft (or Entity if it applies to all entities). A world object could be kept in World; if the entities need pointers to it, you can pass them in the constructor or later via one-time commands. Unfortunately, I don't know Box2D well enough to give more concrete advice. There are certainly people who are experienced with it, and since it's a design discussion, you might want to open your own thread ;)
timo777: The VS 2012 errors should be fixed. Check the next section:
Code on GitHub
Concerning the code base accompanying the book, there was some confusion with its distribution and license, which we intend to clarify by making the code available in a GitHub repository owned by Laurent:
https://github.com/SFML/SFML-Game-Development-Book
Upon request from several users, we added a license that allows you to use the code freely (it only forbids commercial use). Therefore, don't hesitate to extend it and build your own projects :)
-
I'm just curious, why prevent commercial use of the demo code? Isn't it still allowed to write your game yourself using the examples from the book, which will probably look like the final demo code, and use it commercially? Then it would be a bit strange in my opinion, but I'm probably seeing something not good. :)
-
Thank's for both the answers, about Box2d and the license !
-
Code on GitHub
Concerning the code base accompanying the book, there was some confusion with its distribution and license, which we intend to clarify by making the code available in a GitHub repository owned by Laurent:
https://github.com/SFML/SFML-Game-Development-Book
Upon request from several users, we added a license that allows you to use the code freely (it only forbids commercial use). Therefore, don't hesitate to extend it and build your own projects :)
Nice, thank you! :)
I'm just curious, why prevent commercial use of the demo code? Isn't it still allowed to write your game yourself using the examples from the book, which will probably look like the final demo code, and use it commercially? Then it would be a bit strange in my opinion, but I'm probably seeing something not good. :)
It's most probably not something that the authors could decide, but it's what the publisher told them. ;)
But yeah it's not that nice, especially since the provided code is often quite generic C++ & SFML code... :-\
-
Isn't it still allowed to write your game yourself using the examples from the book, which will probably look like the final demo code, and use it commercially?
But yeah it's not that nice, especially since the provided code is often quite generic C++ & SFML code... :-\
I think you understand the limitation in a wrong way. Of course you can use the concepts and ideas and let yourself inspire by our code; after all, we want to teach you something you can use in your own projects. What the license inhibits is copying our code, i.e. marketing our game. In most cases it won't restrict your freedom at all.
To clarify: It is no problem if you use features like the command system in your game, we do not own the patent on these ideas :)
-
Isn't it still allowed to write your game yourself using the examples from the book, which will probably look like the final demo code, and use it commercially?
But yeah it's not that nice, especially since the provided code is often quite generic C++ & SFML code... :-\
I think you understand the limitation in a wrong way. Of course you can use the concepts and ideas and let yourself inspire by our code; after all, we want to teach you something you can use in your own projects. What the license inhibits is copying our code, i.e. marketing our game. In most cases it won't restrict your freedom at all.
To clarify: It is no problem if you use features like the command system in your game, we do not own the patent on these ideas :)
Thank you for clarifying that!
-
@Nexus, I tried compiling again.
But at 07, 08, 09 and 10 I get errors again. First two for every project, now one:
Error 1 error C2100: illegal indirection C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional 1269 1 07_Gameplay
I get the same exact error for the last four projects. Visual Studio says the error is coming from:
_VARIADIC_EXPAND_0X(_CLASS_PMF_WRAP, , , , ) //Here
#undef _CLASS_PMF_WRAP
C2100 means dereferencing a non-pointer, but it doesn't point to a project file... Can you help?
-
This problem is what I mentioned earlier, a bug in the new compiler from Microsoft. I did some fixes and got it to compile I'm gonna check what happened, could be that those fixes disappeared along the way somehow.
-
This problem is what I mentioned earlier, a bug in the new compiler from Microsoft. I did some fixes and got it to compile I'm gonna check what happened, could be that those fixes disappeared along the way somehow.
I thought you were talking about the first error that's now fixed. Could you please tell us if you can find how you fixed it?
-
It's not really possible to fix it, since there is a compiler bug (http://connect.microsoft.com/VisualStudio/feedback/details/773565/cannot-call-const-forwarding-call-wrapper-result-of-std-bind) with std::bind(). As a workaround, we replaced the problematic std::bind() calls with lambda expressions.
-
It's not really possible to fix it, since there is a compiler bug (http://connect.microsoft.com/VisualStudio/feedback/details/773565/cannot-call-const-forwarding-call-wrapper-result-of-std-bind) with std::bind(). As a workaround, we replaced the problematic std::bind() calls with lambda expressions.
Wasn't that the first error? I don't think the second error has anything to do with this bug. Since you get this bug even with the Git repository.
-
They are related from what I remember.
Looking from the source in Laurents repository, something must have gone wrong because I can't find the fix in the code. When I get home I'll check where it went. In any case, fixed version will be up today.
-
I was wrong(, like always).
The error was indeed due the bug with the bind function in:
data[Pickup::HealthRefill].action = std::bind(&Aircraft::repair, _1, 25);
After looking at the other binds, that didn't gave an error, the difference is Aircraft::repair is actually from the "parent" class Entity. Visual Studio seems to have a bug it can't handle functions pointing to a function that's inhereted from a parent. So you will have to implement the same function at Aircraft::repair to let it work.
Could someone do a pull request with this pretty stupid fix? Or at least put a warning there for Visual Studio 2012 and how to fix it.
-
I've done a commit now, let me know if this works. Sorry it took such time but I was on the train and didn't reach my destination until midnight.
doing an proxy function in the sub-class Aircraft is more unclean fix and is more or less forcing your class to work with the tools rather than have the tools fit the task at hand. Kind of like using a screwdriver to hammer in a nail. So instead it's swapped for a boring lambda function:
data[Pickup::HealthRefill].action = [] (Aircraft& a) { a.repair(25); };
It doesn't look as good as the std::bind function and it's kind of hackish, but it is the better of the two.
Also fixed the dumb warnings for VC++11 when you have a switch-statement and cover all possible results.
-
I succesfully added a LUA bind to the "engine" the book make us do.
First of all I get LUA library and Lua SLB, wich is a binder for C++. You can find it here : http://code.google.com/p/slb/
I used the version 2 because I had already used it in the past, but version 3 should be fine.
I dunno if what I did is the best way to do, but here it is :
- I added LUA and Lua SLB headers to my project
- In the ResourcesIdentifiers I added a Scripts namespace with an enum of my scripts
- I created a ScriptPlayer class witch the equivalent of MusicPlayer but for LUA scripts. It has two methods to load scripts : registerFile() and regsterScript() because a LUA script can be in a file or directly in C++ string. The ScriptPlayer is also responsible for storing the lua_State pointer. I pass it to my SceneNode in the Application Context (with other resources managers).
- Then I added a ScriptNode wich keep a pointer onto the ScriptPlayer and plays a script under a certain command or at update or as you want...
- I added functions that bind my essential C++ classes to LUA with SLB. For now I just binded sf::Vector2f, SceneNode and Entity for tests purposes, but you can bind whatever you want.
The result is that I can make a fight between David and Goliath (wich are Entities) in LUA, even move them if I want to :
SLB.using(SLB);
local david = Entity(100);
local goliath = Entity(200);
local position = david:getWorldPosition();
--print("David is at (".. position.x ..":".. position.y ..")");
while ((not david:isDestroyed()) and (not goliath:isDestroyed())) do
if (david:getHealthpoints() < 80) then
-- Heal himself
david:heal(30);
else
-- David attack Goliath
goliath:damage(10);
end
-- Goliath attacks David
david:damage(20);
-- Recap
print("\n----------------------------");
print("David: "..david:getHealthpoints().."HP");
print("Goliath: "..goliath:getHealthpoints().."HP");
print("\n");
end
Exposal look like this :
void exposeVector()
{
SLB::Class<sf::Vector2f>("Vector2f")
.constructor<float, float>()
.property("x", &sf::Vector2f::x)
.property("y", &sf::Vector2f::y);
}
void exposeSceneNode()
{
SLB::Class<SceneNode, SLB::Instance::NoCopy>("SceneNode")
.constructor<Category::Type>()
.set("getWorldPosition", &SceneNode::getWorldPosition);
}
And the ScriptPlayer definition :
class ScriptPlayer : private sf::NonCopyable
{
public:
ScriptPlayer();
~ScriptPlayer();
bool play(Scripts::ID script);
void registerFile(Scripts::ID script, const std::string& filename);
void registerScript(Scripts::ID script, const std::string& content);
private:
lua_State* mLuaState;
std::map<Scripts::ID, std::string> mScripts;
};
If you want to have more sources about that, you're welcome to get an eye on my GitHub repo : https://github.com/Lo-X/potato-framework
You may (and must :p ) need to read the book to understand the "framework"
As I already said, I'm not sure this way to do is the best, but as far as my tests go, it works
-
Hello, hopefully this is in the right place.
I have this book and I'm at the end of chapter 2. However I can't compile it in VS2012. I created the resource holder class almost word-for-word from the book (except for variable name and exception text) and took the code from chapter 1 and changed it so that it should work with the ResourceHolder class.
However, when I try to compile it, I get ton of errors. I have experience with C++ and to me, my code feels like it's OK, I don't see any errors with it. Instead of reposting it here, here is link to stackoverflow where I originally posted this question.
http://stackoverflow.com/questions/17876510/visual-studio-wont-compile-template-class-with-inl-implementation#17876808
If you could tell me what I'm doing wrong, I would be very glad.
-
The code on the PacktPub website is not the latest version. Try the one from the GitHub repository:
https://github.com/SFML/SFML-Game-Development-Book
-
I downloaded the .zip of github code and I'd say that cmake script could be improved, because:
- I go to main dir (the one with cmake lists)
- I use "cmake ."
- I use "make"
- Then I switch to dir 09/Source (the one with binary) and I launch the app "./09_Audio" and I got:
EXCEPTION: ResourceHolder::load - Failed to load Media/Sound/AlliedGunfire.wav
The solution is to tell cmake to place binaries in "09_Audio/" rather than "09_Audio/Source".
-
I downloaded the .zip of github code and I'd say that cmake script could be improved, because:
The solution is to tell cmake to place binaries in "09_Audio/" rather than "09_Audio/Source".
Fix it and make a pull request. :P
-
Hi!
I purchased this book and are eager to read it. Normally I would not buy books on Amazon that does not have a preview, so I would recommend that you (the authors) write an email to PacktPub about that. But in this case I support SFML by buying this book. :)
Also it would not hurt if there was more customer reviews.
From what I could tell all those chapters look like they are packed with good stuff, like networking for instance.
Typically that's an area most game dev books just skims over only to show how to send a TCP/UDP-packet. But totally ignores to go deeper on how to make LAN/Internet game (i.e: a 2d tank internet game ). So my hopes is high on this one.
Thanks for make a great community!
-
The book covers how to not just send packages but how to actually utilize it in your game as well :)
Hope you will enjoy the book!
-
Thanks for buying the book! Concerning preview: on the PacktPub site (http://www.packtpub.com/sfml-game-development/book), there is a detailed description, a table of contents and a sample chapter :)
-
I'm perhaps mistaken but I think there's some preview with the Amazon Kindle as well, weird that tere's not preview on Amazon website.
Good reading, you'll enjoy the network part :p
-
Thanks to the book, I implemented my first QuadTree today !
Taking advantage of C++11 and the SceneNodes and Command power, it was pretty easy to implement another tree that takes collidable SceneNodes and add them in the right Quad.
Well, this is a pretty simple QuadTree. It does not create children in function of the number of objects in it (yet). Still it can stores objects and return close objects from another one. Handy for collision tests or targeting.
The QuadTree class look like :
class QuadTree
{
public:
QuadTree(int level, const sf::FloatRect& bounds);
void insert(SceneNode *object);
void clear();
const sf::FloatRect& getBounds() const;
void getCloseObjects(SceneNode* from, std::deque<SceneNode*>& returnedObjects);
private:
bool isFinal() const;
bool hasChildren() const;
void split();
int getChildIndex(const sf::FloatRect& rect);
private:
sf::FloatRect mBounds;
int mLevel;
int mMaxLevel = 4;
std::deque<SceneNode*> mObjects;
std::array<QuadTree*,4> mChildren;
};
Thanks to authors, filling the QuadTree is as simple as :
Command command;
command.category = Category::All;
command.action = derivedAction<CollideNode>([this] (SceneNode& node, sf::Time) {
mQuadTree.insert(&node);
});
mScene.onCommand(command, dt);
As for the LUA bind I made, that code is available freely and completely on GitHub. Questions or comments are welcome (perhaps by MP).
Awesome book. I kinda doubled things I can do in video game developpement !
-
This is a great leap forward for the productivity of SFML, having a first book released (even if it costs some coins) it will motivate a lot of users to start writing there own books for SFML.
-
It is awesome to see you invent new stuff with what we provide. Though wondering, is it not possible to make the scene graph into the actual quad tree? The branch nodes would simply be scene nodes. It might be a bit more work though but would be nice to not have two structures refer to the objects.
-
It is awesome to see you invent new stuff with what we provide. Though wondering, is it not possible to make the scene graph into the actual quad tree? The branch nodes would simply be scene nodes. It might be a bit more work though but would be nice to not have two structures refer to the objects.
Hi,
I thought about that. The problem I have is that the QuadTree is rebuilt every frame (or each time there's movement). So I need to have SceneNodes stored somewhere. Of course that somewhere can be a simple vector, but I like the advantages of Tree.
Of course, there's perhaps a solution I can not think about to have only a QuadTree and yes, It would be better not to have two stuctures. I'm open to ideas =) I perhaps need to dig into the restructuration of a SceneGraph given a "parameter" (in our case position, but why not something else like a z-index or something).
-
Why resource manager uses std::map instead of std::unordered_map?
You don't iterate through resources so unordered_map should be faster (by how much, it depends on the compiler's implementation but still I think adding one word for even small improvment is a good thing).
-
Why resource manager uses std::map instead of std::unordered_map?
You don't iterate through resources so unordered_map should be faster (by how much, it depends on the compiler's implementation but still I think adding one word for even small improvment is a good thing).
I've been thinking the same when reading it.
Also since they are already using some C++11 features, std::unordered_map wouldn't be an awkward addition.
Then again, given that it's not something that gets accessed that many times per frame iteration, the performance increase will probably be very small.
-
The possible performance advantage of std::unordered_map comes at a cost, most notably memory. Additionally, hash maps require an operator== and a hash function, of which especially the latter isn't necessarily available. Keep in mind that the Identifier template parameter is not constrained to enums.
Since ResourceHolder::get() is only called a few times at initialization, the access time is irrelevant in relation to other parts of the application. On the other hand, we don't waste memory for an advantage that we can't exploit.
-
Could you explain me why SceneNode and Entity were split in two classes?
Is it like SceneNode is for drawing & collisions while Entity is for the rest of logic? Why it's not just one class? Collisions seem to be logic part and not drawing part...
-
SceneNodes are just generic nodes in the tree, to imply we can have any kind of derived node types for any kind of thing in our game world.
From that, we built Entity as a base class for all our entity types. Entity's behavior could be made in the SceneNode class, but we did it this way instead to leave SceneNode as generic as possible.
So, basically, Entity has attributes like health and velocity which are common to all our entity types, while those attributes don't need to exist in other SceneNode types.
Hope it's clear :))
-
I just finished chapter 3 and for some reason, when I try to run the game, the background isn't drawn.
I compared my code to github code they are exactly the same, apart from variable names. Did anyone else had this problem?
I don't have much experience with game programming, but I suspect it has something to do with mSceneLayers not being iterated over and drawn, but don't hold me on that.
-
I compared my code to github code they are exactly the same, apart from variable names.
Does it work if you try the GitHub code directly?
Which compiler and operating system do you use?
-
Does it work if you try the GitHub code directly?
Which compiler and operating system do you use?
I found where the problem was, although I have no idea that this could cause this. In the SpriteNode class, there is an drawCurrent() method declared as this:
virtual void drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const;
but I had it like this:
virtual void drawCurrent(sf::RenderTarget& target, sf::RenderStates& states) const;
I passed the second argument as reference. I deleted the & and now it works properly.
-
The signature must match the virtual member function of the base class exactly in order to override it.
Otherwise, you define a new, different function in the derived class. So, the base class version will be called.
-
I've been moving stuff around the screen since I started with SFML 1.6, but the section on Vector Algebra stuck in my mind.
I've been moving objects like that, of course, but...Today it has solved for me (in one line of code), a tricky problem that made me 'nerdgasm' at how easy the solution actually was.
Thus far that alone is worth buying the book for. [read as: waking up a math dunce]
-
May you paste this line here? I'm curious about it now. ;D
-
Well done on getting that book out. I've been messing about with SFML for a few years now and just started reading the eBook. Great stuff and thanks for all your support for the community!
-
Just bought the book and I'm about half way through. It flows extremely well and has been a great read so far. It's filled many gaps in my game dev knowledge and refined what I thought I already knew. Exactly the kind of book I've been looking for.
Thank you to all the authors! :)
-
Just bought the book, I am excited to see what I can learn from it. Always amazed by the support SFML has.
-
Is there another way to get source files, because http://www.packtpub.com/support/12705 doesn't seem to work - the email is not in my mailbox.
-
https://github.com/SFML/SFML-Game-Development-Book
Those should be fine :D
-
https://github.com/SFML/SFML-Game-Development-Book
Those should be fine :D
Heh, just found that one a few minutes after posting here... :D Thanks anyway.
-
I have just received my copy of the book. I am now hoping that reading through this will help me polish the first version of my first project. :)
Anyway, big thanks to the authors for making it real !
-
Just purchased the book last week and am working my way though it. I am converting the code listed into C#, which is proving quite fun and I am learning a lot about game development techniques in general. Great book, would buy again!
Also registered an account just to say how good this book is, :P
-
In chapter 2 (page 37) it is said:
We do not store the sf::Texture directly, but we wrap it into a std::unique_ptr.
This design choice is not well explained, in particular why having elements of the map as pointers to textures instead of plain textures better. Could anyone list pros and cons of both choices?
In my current project, I first started with (unique) pointers to textures, before switching to plain textures. It is of course more simple to handle, and so far I have found nothing bad this way.
-
Unique pointers are more flexible and generic, because they don't require:
- Copy or move semantics
- Default constructor
The first point is a requirement for STL containers, the second for some of the operations. For sf::Texture, this is not a problem, but sf::Shader and sf::Music can't be copied (although the music is not used in ResourceHolder). C++11 emplacement would be a partial solution, but is not supported by our target compilers.
The disadvantage is an additional indirection and heap allocation, but in relation to the heavy resources this should be reasonable. If you don't need the flexibility, you can of course use plain objects.
-
I am having an issue compiling chapters 7-10. I read through the thread and saw a few others were affected. The solution Groogy provides at the bottom of page 6 does not work for me and I see no one else confirming the workaround for VC++11 users.
To be clear I receive the following errors when compiling chapters 7-10.
error C2100: illegal indirection
and
error C3849: function-style call on an expression of type 'const std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>' would lose const and/or volatile qualifiers for all 2 available operator overloads
I verify there are no additional changes in the repository on GitHub for "SFML-Game-Development-Book / 07_Gameplay / Source /". I then make the one line change Groogy suggests in DataTables.cpp at the end of page 6.
data[Pickup::HealthRefill].action = [] (Aircraft& a) { a.repair(25); };
The error about indirection is gone, but I still receive the following error.
error C3849: function-style call on an expression of type 'const std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>' would lose const and/or volatile qualifiers for all 2 available operator overloads
-
I am having an issue compiling chapters 7-10. I read through the thread and saw a few others were affected. The solution Groogy provides at the bottom of page 6 does not work for me and I see no one else confirming the workaround for VC++11 users.
I assume you're using VS 11 then, right?
For me everything built fine with VS 11, so I'm not sure where the problem originates from on your end. Is you VS version up-to-date?
[ 1%] Built target 01_Intro
[ 1%] Built target 02_Resources
[ 5%] Built target 03_World
[ 10%] Built target 04_Input
[ 19%] Built target 05_States
[ 30%] Built target 06_Menus
[ 44%] Built target 07_Gameplay
[ 61%] Built target 08_Graphics
[ 79%] Built target 09_Audio
[100%] Built target 10_Network
Install the project...
-
Try the code from GitHub, not the one on the PacktPub site.
-
I pulled down the SFML-Game-Development-Book repository and I was able to successfully build all the projects with VC++11. Chapter 7 now runs successfully.
Chapters 8-10 load into the menus, but when I press the "play" button the game crashes.
I am about a quarter into the book and enjoying it.
-
Chapters 8-10 load into the menus, but when I press the "play" button the game crashes.
You use the original code and have followed the ReadMe.txt step by step?
If so, can you debug to see where the game crashes, and why? Is there anybody else who can reproduce this issue?
-
I think I found a mistake in p.61.
On p. 58/59, SceneNode has a private drawCurrent() member function.
Entity inherits from SceneNode. Entity cannot see SceneNode's drawCurrent(), which is private.
On p. 61, Aircraft inherits from Entity. Aircraft cannot see SceneNode's drawCurrent(), which is private.
Aircraft declares a public drawCurrent() member function. It doesn't override SceneNode's drawCurrent(), which isn't even visible; since a new definition is being provided, rather drawCurrent() is being redefined in Aircraft. Otherwise it would break the access control system, by allowing the programmer to inherit a private virtual function and make it public in a derived class.
The text says the member function is being overridden; I think the function is being redefined.
Of course, I might be wrong and someone more knowledgeable in C++ than I am could clarify this.
-
It's right that Aircraft::drawCurrent() should be private, thanks for noticing. However, the access specifier has no influence on overriding or redefining, only the function signature does. And since the latter is equal in both classes, the function is overriden.
-
It's right that Aircraft::drawCurrent() should be private, thanks for noticing. However, the access specifier has no influence on overriding or redefining, only the function signature does. And since the latter is equal in both classes, the function is overriden.
Hmm. So you mean that, even though Aircraft::drawCurrent() is declared to be public, it's actually private? I looked left and right for a thorough explanation, but only came across this (http://stackoverflow.com/questions/2671448/access-specifier-while-overriding-methods) and this (http://www.drdobbs.com/conversations-virtually-yours/184403760).
C++ has many dark corners, but I don't think this should be one of them. The compiler should just stamp its foot and refuse to compile such code. It's ambiguous and confusing.
-
Hmm. So you mean that, even though Aircraft::drawCurrent() is declared to be public, it's actually private?
No, it's public. But it still overrides the private method SceneNode::drawCurrent(). Access specifiers and overriding are orthogonal concepts.
Mentioning the identifier Base::drawCurrent explicitly in derived classes is still not allowed, since it's private.
C++ has many dark corners, but I don't think this should be one of them. The compiler should just stamp its foot and refuse to compile such code. It's ambiguous and confusing.
A warning might indeed be appropriate if an access specifier is changed through inheritance, because this is mostly not intentional.
-
Hmm. So you mean that, even though Aircraft::drawCurrent() is declared to be public, it's actually private?
No, it's public. But it still overrides the private method SceneNode::drawCurrent(). Access specifiers and overriding are orthogonal concepts.
Mentioning the identifier Base::drawCurrent explicitly in derived classes is still not allowed, since it's private.
C++ has many dark corners, but I don't think this should be one of them. The compiler should just stamp its foot and refuse to compile such code. It's ambiguous and confusing.
A warning might indeed be appropriate if an access specifier is changed through inheritance, because this is mostly not intentional.
Spot on (http://gcc.gnu.org/ml/gcc-help/2013-10/msg00030.html). With any luck, it will trigger a warning in a future release of GCC.
Is this going to make it to the errata and/or GitHub?
-
Just bought the book and registered to say thanks! Just started working through the first chapter tonight and this is exactly the type of book I've been looking for. The language you use in it, and the way you explain things is a lot more approachable than other game dev books I've come across.
Writing my first game for a 3000 level C++ OOP class, and I couldn't have asked for a better reference :)
-
Good to hear, thank you :)
By the way, the private issue was fixed on GitHub.
-
Just trying my first attempt at compiling the book files with Cmake and encountered this error...
The C compiler identification is MSVC 16.0.30319.1
The CXX compiler identification is MSVC 16.0.30319.1
Check for working C compiler using: Visual Studio 10
Check for working C compiler using: Visual Studio 10 -- broken
CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/CMakeTestCCompiler.cmake:61 (message):
The C compiler "C:/Program Files (x86)/Microsoft Visual Studio
10.0/VC/bin/cl.exe" is not able to compile a simple test program.
Is my compiler at fault here? I don't have much experience with CMake.
-
The error can be of multiple origins. Make sure you run the latest version of CMake and make sure you've installed all updates for VS 2010 - in fact I'd suggest to upgrade to VS 2013. ;)
Also don't forget to clear the CMake cache and a clean rebuilt.
-
Latest CMake - check.
VS2010 up to date - check.
Cache cleared - check.
These were all checked prior to posting. Tried VS2013 (it has some nice things in it, I like! :) ). I'll leave it and SFML until they're officially married.
Still an odd thing though with VS2010 on my PC. Not sure why CMake is so upset.
No biggie, I'll play around with the source in a fresh project and see how it goes.
-
As I read the book I find myself wanting to ask a few questions. Is there a forum or appropriate place to discuss aspects of the book?
-
Here :)
-
There isn't a dedicated place for the SFML book - maybe Laurent could create a sub forum?
But people have been using this thread and been creating thread here on the forum when they had questions about certain things, so feel free to do so as well. Nexus, Grimshaw and Groogy (the three authors) are more or less regularly on the forum and other readers of the book might know a few things to say as well. :)
-
I'm having an issue understanding the syntax of the derivedAction function. Using std::function is new to me and is the crux of the issue. I have included the entire function at the bottom.
std::function<void(SceneNode&, sf::Time)> derivedAction(Function fn)
The "std::function<void(SceneNode&, sf::Time)>" specifies the signature for the function derivedAction takes as a parameter. However, this doesn't seem to jive with the examples from http://en.cppreference.com/w/cpp/utility/functional/function (http://en.cppreference.com/w/cpp/utility/functional/function). My understanding is that it should be specifying the signature for derivedAction.
moveLeft.action = derivedAction<Aircraft>(AircraftMover(-playerSpeed, 0.f));
I'm confused with the use of "<Aircraft>".
template <typename GameObject, typename Function>
std::function<void(SceneNode&, sf::Time)> derivedAction(Function fn)
{
return [=] (SceneNode& node, sf:Time dt)
{
// Check if cast is safe
assert(dynamic_cast<GameObject*>(&node) != nullptr);
// Downcast node and invoke function on it
fn(static_cast<GameObject&>(node), dt)
};
}
-
derivedAction<GameObject, Function> is a function template, that is, when you fill in the template parameters, a function is instantiated. There are two template parameters:
- GameObject: The derived class that you specify explicitly in calling code. A possible argument for this template parameter is Aircraft.
- Function: The type of callable object you pass as a function parameter, which is deduced by the compiler. "Callable object" can be a function pointer, a functor, or a lambda expression.
The whole idea behind derivedAction() is to take a function that operates on derived classes, using the signature
void(GameObject& object, sf::Time dt)
and to transform it to a function that operates on base classes with the signature
void(SceneNode& object, sf::Time dt)
This allows to store multiple commands in the same container, although they internally dispatch to different classes.
These are rather advanced techniques, but they allow a great simplification. Without derivedAction, we would have to downcast the parameter every time we define a command that runs on a derived class. The derivedAction function template encapsulates this task.
If you don't understand some of the terminology I used in this post, I recommend looking up function templates, function objects and std::function. These are very powerful C++ concepts, and the command system described in the book relies heavily on them.
-
I'm loving the book so far!
I had a quick question. How does the second toString function, in chapter 6's Utility.hpp file, work? I can't figure out what, exactly, #define BOOK_KEYTOSTRING_CASE(KEY) case sf::Keyboard::KEY: return #KEY;
does. Any help would be appreciated!
-
I haven't read the book but I assume the crux of your question/confusion is the special meaning of # in preprocessor macros. Basically, #KEY turns into "KEY". So sf::Keyboard::A turns into "A", and so on.
-
I really like the book. I remember about reading about keys that are pressed down. There was an information about this special behavior computers have where if you have a cursor in a document and you hold down a key (let's say right arrow) in order to move the cursor right, it will move instantly, then pause for a split second and then move very fast.
I think it was in a chapter about events, but I read it again and didn't find it.
If anyone of you, guys, know in which chapter it is or if you can explain to me how it works and how it affects the game, please let me know, because I can't even find it on Google :-)
-
I currently don't have to book next to me, but you can find some explanation in the official SFML tutorial (http://www.sfml-dev.org/tutorials/2.1/window-events.php#the-keypressed-and-keyreleased-events).
-
You mean key repetition? That should be explained in the chapter about user input.
You can also read the docs of sf::Window::setKeyRepeatEnabled().
-
I have a few questions related to the book.
First, I am looking for a way to draw/visualize the systems used in the book. For example, I have read and reread how commands are applied to the SceneGraph. However, I just keep forgetting how they interact and this is true of a number of systems. I need a technique to draw the interactions, so I can reference them now and then until they sink in. Do you have any recommendations for this type of approach?
Next, I have a couple c++ 11 questions.
In the following snippet of code why is this needed in the capture list? Is it so createProjectile is in scope?
mMissileCommand.action = [this, &textures] (SceneNode& node, sf::Time)
{
createProjectile(node, Projectile::Missile, 0.f, 0.5, textures);
};
Why is the std::placeholders::_1 used here, when the increaseSpread function takes zero parameters.
data[Pickup::FireSpread].action = std::bind(&Aircraft::increaseSpread, _1);
void Aircraft::increaseSpread()
{
if (mSpreadLevel < 3)
++mSpreadLevel;
}
Finally, here's a small correction I noticed in chapter 7 under the subtitle Displaying Text. The author mentions the method Aircraft::update when they meant Aircraft::updateTexts.
In the method Aircraft::update(), we check for the current hitpoints, and convert them to a string, using our custom toString() function.
-
I need a technique to draw the interactions, so I can reference them now and then until they sink in. Do you have any recommendations for this type of approach?
There are quite a few diagrams in the book, especially one that visualizes how events and commands are propagated through the different classes. You could take them as inspiration, and expand them according to your needs. What do you have in mind concretely?
Next, I have a couple c++ 11 questions.
this can be considered an implicit function parameter. If you call a member function (createProjectiles()) in a lambda expression, you need to capture this. If you bind a member function, you can use _1 to forward the first parameter as this.
Finally, in chapter 7 under the subtitle Displaying Text the author mentions the method Aircraft::update when they meant Aircraft::updateTexts. I wanted to point this out in case it hasn't been noticed.
Thanks for the notice!
-
The diagram you used to demonstrate the flow of commands in Ch 4 was very helpful. It's what made me realize it be really helpful to have a visual representation of classes and their interactions. That got me wondering whether there was an popularized convention for diagramming different aspects of code?
Also, could you respond to the std::placeholders question? I looked up a number of references, but still don't understand why a placeholder is being set for a function that doesn't have a parameter.
-
That got me wondering whether there was an popularized convention for diagramming different aspects of code?
UML is quite hyped in the field of OOP. But especially when you do it for yourself, it's questionable whether strictly adhering to such standards is helpful -- depending on the programming language and personal preference, it may be worthwhile to model code design in a different way. Personally, I like to sketch things with pen and paper, similar to the diagrams in the book (and sometimes with more information).
Also, could you respond to the std::placeholders question?
I did. To expand on my previous answer: In std::bind() contexts, this is always considered the first parameter.
Let's look at our example: We are given
void Aircraft::increaseSpread();
, a member function with no parameter. This declaration is, apart from access rights, semantically equivalent to a global function with one parameter, namely a pointer to the object -- in other words, this.
void increaseSpread(Aircraft* this);
When you bind this function, you can therefore use the placeholder _1 to forward the first argument of the resulting callable as the this pointer in the original function.
std::bind(&Aircraft::increaseSpread, _1);
yields a unary functor:
struct Bound
{
void operator() (Aircraft& argumentToForward);
};
If it's still not clear, I suggest reading the documentation of std::bind() in details. These things are all explained.
-
That got me wondering whether there was an popularized convention for diagramming different aspects of code?
UML is quite hyped in the field of OOP. But especially when you do it for yourself, it's questionable whether strictly adhering to such standards is helpful -- depending on the programming language and personal preference, it may be worthwhile to model code design in a different way. Personally, I like to sketch things with pen and paper, similar to the diagrams in the book (and sometimes with more information).
I drew UML class diagrams for chapters 3, 4 and 5 with Violet UML Editor (http://alexdp.free.fr/violetumleditor/page.php?id=en:tour) - it's free and very easy to use.
I'm a visual learner, so the class diagrams really helped me to figure things out.
-
Thanks Nexus, you made that very clear. Also, thanks georger for the heads up. I downloaded Violet and will give it a shot. I think this will be very helpful for me.
-
Previously, I had said chapters 8-10 were crashing on entering gameplay (reply #127). I've made it to chapter 8 and started looking into it. What happens is an exception is thrown when trying to load the jungle texture. The message i receive is "Failed to create texture, its internal size is to high (1024x4023, maximum is 2048x2048)."
I've switched to the desert texture and it allows me to play the game. I've never seen the intended gameplay, but it's running at about 26-30 fps and feels a little choppy. The effect on HP text, bullets, and pickups seems to be leaving cloud bursts (I've attached a screenshot). I'm assuming these are the shader effects that are being introduced.
-
The error simply means, that your graphics card can only handle texture with a maximum size of 2048x2048 and the jungle texture is bigger than that.
In combination with the low FPS, it really seems like your graphics card is not directly made for the developed game.
But there are things you could do. If you're not already doing so, you should run the game in release mode. Then you can also split the texture into smaller pieces. This will require some extra logic, but at least that way you can use the image. How is the performance if you turn off shaders?
-
I only mentioned the issue with the jungle texture, because previously I had said chapters 8-10 were crashing and that was the issue.
I've finished chapter 8 now and can definitely say the issue is the bloom effect which uses shaders.
PostEffect::isSupported()
This returns true, but my video card just can't handle it, so I have simply commented out the alternative draw code in World::draw(). The previously FPS numbers were from release mode. With shaders disabled I have jumped up to 160 FPS from 1 FPS in debug mode.
-
With Ch 8's code I have been experiencing a crash when the game transitions from the GameOverState from either finishing the level or dying. I've set a breakpoint within StateStack::applyPendingChanges() on mStack.clear(). The mPendingList contains an Action to perform a clear and then push the MenuState. The stack itself contains the GameState and the GameOverState. Everything looks good. When I continue I get the following.
Unhandled exception at 0x1002CA1C (ig4icd32.dll) in 08_Graphics.exe 0xC0000005: Access violation writing location 0x0000001C.
To be safe I got the most recent code from Laurent's SFML-Game-Development-Book repo. I realized this did not occur in Ch 7, so I began removing new additions. To be clear the following two changes are the only changes I have made to the code.
First I comment out the drawing of the shader.
void World::draw()
{
// if (PostEffect::isSupported())
// {
// mSceneTexture.clear();
// mSceneTexture.setView(mWorldView);
// mSceneTexture.draw(mSceneGraph);
// mSceneTexture.display();
// mBloomEffect.apply(mSceneTexture, mTarget);
// }
// else
// {
mTarget.setView(mWorldView);
mTarget.draw(mSceneGraph);
// }
}
The crash will still occur, but if I then comment out the following line from the body of World's ctor the crash goes away.
// mSceneTexture.create(mTarget.getSize().x, mTarget.getSize().y);
My understanding of the access violation is that a read or write is occurring to memory that cannot be accessed. The usage of the sf::RenderTexture looks nearly identical to documentation provided on this site. I've inspected the object and that looks good too.
I'm not so concerned with the issue. I can't use shaders regardless, but it does bother me I don't have an idea how to debug this. What approach should I take? Thanks.
-
Does your system support render textures? As far as I know, SFML provides a fallback when FBOs are not supported, but I don't know the details here.
Shaders are not supported at all, or do the examples in the SFML SDK work?
Is there an error message on the console?
-
Does your system support render textures?
I thought so. The call to
mSceneTexture.create(mTarget.getSize().x, mTarget.getSize().y);
returns true. That being said I searched around and dug a couple threads on render textures and Intel GPUs.
http://en.sfml-dev.org/forums/index.php?topic=9149.0 (http://en.sfml-dev.org/forums/index.php?topic=9149.0)
https://github.com/SFML/SFML/issues/418 (https://github.com/SFML/SFML/issues/418).
Both issues have been fixed and neither sounds similar to what I am experiencing, but it is concerning as I have an Intel GPU.
Shaders are not supported at all, or do the examples in the SFML SDK work?
Shaders are supported. I can run the book code, but it just performs poorly. I tested the SFML SDK shader example and it ran smoothly.
Is there an error message on the console?
No error message.
-
Might it be that the size is too big for the sf::RenderTexture (since you reported a similar issue with sf::Texture)? As far as I know however, in OpenGL the FBO size is only limited by the size of the attached texture, and 2048x2048 is bigger than the window. Another OpenGL error might also be possible (e.g. out of memory), but they should be reported by SFML. Do you compile in debug mode, and link the SFML debug libraries?
Can you use a sf::RenderTexture with the same size in a separate project?
Generally, the "Access violation writing location 0x0000001C" may indicate null pointer dereferencing (the address is quite close to 0). Do you have the stack trace for it? Is the access violation invoked during clear()? If so, there is undefined behavior elsewhere...
-
Do you compile in debug mode, and link the SFML debug libraries?
Yes, I do.
Can you use a sf::RenderTexture with the same size in a separate project?
No , I cannot. I have created a very small test that generates the exact same error.
Unhandled exception at 0x1002CA1C (ig4icd32.dll) in HelloWorld.exe: 0xC0000005: Access violation writing location 0x0000001C.
When you close the window the access violation will occur. The timing is similar to what is occurring with the book's code. The book's access violation occurs when the player either dies or finishing the mission causing the GameState and GameOverState to begining destroying its resources.
You'll notice I only create the RenderTexture and never use it. The access violation occurs regardless.
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(1024, 768), "SFML works!");
sf::RenderTexture mSceneTexture;
mSceneTexture.create(1024, 768);
sf::Texture mTexture;
mTexture.loadFromFile("Textures/Entities.png");
sf::Sprite mSprite;
mSprite.setTexture(mTexture);
mSprite.setPosition(100.f, 100.f);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(mSprite);
window.display();
}
return 0;
}
Do you have the stack trace for it?
ig4icd32.dll!1002ca1c() Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for ig4icd32.dll]
ig4icd32.dll!1002dae2() Unknown
sfml-graphics-d-2.dll!589c6bf0() Unknown
sfml-graphics-d-2.dll!589c7326() Unknown
sfml-graphics-d-2.dll!5899bf72() Unknown
Sandbox.exe!`eh vector destructor iterator'(void * ptr, unsigned int size, int count, void (void *) * pDtor) C++
Sandbox.exe!std::array<sf::RenderTexture,2>::~array<sf::RenderTexture,2>() C++
Sandbox.exe!BloomEffect::~BloomEffect() C++
Sandbox.exe!World::~World() C++
Sandbox.exe!GameState::~GameState() C++
Sandbox.exe!GameState::`scalar deleting destructor'(unsigned int) C++
> Sandbox.exe!std::default_delete<State>::operator()(State * _Ptr) Line 1152 C++
Sandbox.exe!std::unique_ptr<State,std::default_delete<State> >::_Delete() Line 1445 C++
Sandbox.exe!std::unique_ptr<State,std::default_delete<State> >::~unique_ptr<State,std::default_delete<State> >() Line 1400 C++
Sandbox.exe!std::unique_ptr<State,std::default_delete<State> >::`scalar deleting destructor'(unsigned int) C++
Sandbox.exe!std::allocator<std::unique_ptr<State,std::default_delete<State> > >::destroy<std::unique_ptr<State,std::default_delete<State> > >(std::unique_ptr<State,std::default_delete<State> > * _Ptr) Line 624 C++
Sandbox.exe!std::allocator_traits<std::allocator<std::unique_ptr<State,std::default_delete<State> > > >::destroy<std::unique_ptr<State,std::default_delete<State> > >(std::allocator<std::unique_ptr<State,std::default_delete<State> > > & _Al, std::unique_ptr<State,std::default_delete<State> > * _Ptr) Line 758 C++
Sandbox.exe!std::_Wrap_alloc<std::allocator<std::unique_ptr<State,std::default_delete<State> > > >::destroy<std::unique_ptr<State,std::default_delete<State> > >(std::unique_ptr<State,std::default_delete<State> > * _Ptr) Line 909 C++
Sandbox.exe!std::_Destroy_range<std::_Wrap_alloc<std::allocator<std::unique_ptr<State,std::default_delete<State> > > > >(std::unique_ptr<State,std::default_delete<State> > * _First, std::unique_ptr<State,std::default_delete<State> > * _Last, std::_Wrap_alloc<std::allocator<std::unique_ptr<State,std::default_delete<State> > > > & _Al, std::_Nonscalar_ptr_iterator_tag __formal) Line 89 C++
Sandbox.exe!std::_Destroy_range<std::_Wrap_alloc<std::allocator<std::unique_ptr<State,std::default_delete<State> > > > >(std::unique_ptr<State,std::default_delete<State> > * _First, std::unique_ptr<State,std::default_delete<State> > * _Last, std::_Wrap_alloc<std::allocator<std::unique_ptr<State,std::default_delete<State> > > > & _Al) Line 80 C++
Sandbox.exe!std::vector<std::unique_ptr<State,std::default_delete<State> >,std::allocator<std::unique_ptr<State,std::default_delete<State> > > >::_Destroy(std::unique_ptr<State,std::default_delete<State> > * _First, std::unique_ptr<State,std::default_delete<State> > * _Last) Line 1480 C++
Sandbox.exe!std::vector<std::unique_ptr<State,std::default_delete<State> >,std::allocator<std::unique_ptr<State,std::default_delete<State> > > >::clear() Line 1416 C++
Sandbox.exe!StateStack::applyPendingChanges() Line 91 C++
Sandbox.exe!StateStack::update(sf::Time dt) Line 24 C++
Sandbox.exe!Application::update(sf::Time dt) Line 81 C++
Sandbox.exe!Application::run() Line 57 C++
Sandbox.exe!main() Line 13 C++
Sandbox.exe!__tmainCRTStartup() Line 536 C
Sandbox.exe!mainCRTStartup() Line 377 C
kernel32.dll!74bd336a() Unknown
ntdll.dll!76f69f72() Unknown
ntdll.dll!76f69f45() Unknown
-
Can you use a sf::RenderTexture with the same size in a separate project?
No , I cannot. I have created a very small test that generates the exact same error.
Okay, so it's definitely a problem with SFML or the graphics driver (I tend to assume the latter, since render textures seem to work fine on most systems).
I don't know how much you can do apart from debugging your minimal example and trying to find out the cause (maybe open a new thread if you want to discuss this further). But it might as well be a waste of time if it's a driver bug of an old graphics card that will never be fixed :-\
-
I think it will be easy to let this one go. I want to wrap up the book and begin my own project. Thanks again.
-
The publisher has a $5 E-Book Bonanza, so right now it's only 5$ at http://www.packtpub.com/
Thought people might be interested.
-
I'm in the middle of reading the book and I decided to look at the source code to try to get a better understanding of they are teaching. However, I'm having trouble understanding the FOREACH statement
// Preprocessor trick to allow nested loops
#define BOOK_PP_CAT_IMPL(a, b) a ## b
#define BOOK_PP_CAT(a, b) BOOK_PP_CAT_IMPL(a, b)
#define BOOK_ID(identifier) BOOK_PP_CAT(auroraDetail_, identifier)
#define BOOK_LINE_ID(identifier) BOOK_PP_CAT(BOOK_ID(identifier), __LINE__)
// Macro to emulate C++11 range-based for loop
// Instead of for (decl : range) you write FOREACH(decl, range) as in the following example
//
// std::vector<int> v = ...;
// FOREACH(int& i, v)
// {
// i += 2;
// }
#define FOREACH(declaration, container) \
if (bool BOOK_LINE_ID(broken) = false) {} else \
for (auto BOOK_LINE_ID(itr) = (container).begin(); BOOK_LINE_ID(itr) != (container).end() && !BOOK_LINE_ID(broken); ++BOOK_LINE_ID(itr)) \
if (bool BOOK_LINE_ID(passed) = false) {} else \
if (BOOK_LINE_ID(broken) = true, false) {} else \
for (declaration = *BOOK_LINE_ID(itr); !BOOK_LINE_ID(passed); BOOK_LINE_ID(passed) = true, BOOK_LINE_ID(broken) = false)
I understand what it is being used for and how it is implemented, but I can't get how it actually works. I'm hoping somebody could help me out, that would be appreciated.
-
You do not need to know how the FOREACH macro works. The only reason it exists, is because VS 2010 doesn't support range based for loops.
Consider the FOREACH macro a language feature. I don't think you've gone through all the code of SFML or the STL to understand how it works, they provide APIs and how it's implemented doesn't matter for you. ;)
-
Hi,
This book looks great. A quick question, is the source code available for download for both the ebook and print versions?
-
Hi,
This book looks great. A quick question, is the source code available for download for both the ebook and print versions?
Well this has been answered multiple times in this and other threads.... But the code is available on GitHub here (https://github.com/SFML/SFML-Game-Development-Book).
-
Hi everyone!
I've just finished reading the 3rd chapter and got a problem - my ships are always positioned in the left top corner of the view, and, moreover, I can see them only after the view is scrolled up completely to its top border (better see on the screenshot).
http://yadi.sk/d/XjD72sGBF8UVZ (http://yadi.sk/d/XjD72sGBF8UVZ)
I rechecked my code several times - everything is like in the book. I would appreciate any help.
I'm using SFML 2.1 on Mac OS X 10.9.
Thanks.
-
I rechecked my code several times - everything is like in the book. I would appreciate any help.
What does "like" mean, did you write the code yourself? It looks as if the airplanes have position (0,0).
Can you download the code from GitHub (https://github.com/SFML/SFML-Game-Development-Book) and compile it 1:1, without applying any changes?
-
What does "like" mean, did you write the code yourself? It looks as if the airplanes have position (0,0).
Can you download the code from GitHub (https://github.com/SFML/SFML-Game-Development-Book) and compile it 1:1, without applying any changes?
I do not know why, but I haven't tried to compile original source from Github. Now as I did compile it and it worked fine, it turned out to be a problem in my code and I was able to find it.
The problem was in Aircraft::drawCurrent method. My method looked like this:
void Aircraft::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const {
target.draw(mSprite);
}
I forgot to pass states as the second parameter to braw. It should be:
void Aircraft::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const {
target.draw(mSprite, states);
}
Thanks for helping!
-
Hey everyone,
the book really gives insight into some nice concepts. But I have a question concerning the ResourceHolder class template.
template <typename Resource, typename Identifier>
Resource& ResourceHolder<Resource, Identifier>::get(Identifier id)
{
auto found = mResourceMap.find(id);
assert(found != mResourceMap.end());
return *found->second;
}
Why is the only error checking that's being done here an assert? Once we go into release and turn debug mode off, the found iterator may as well point to one-past-the-end. Shouldn't we always make sure that it is not .end() before using it?
-
Have you read Chapter 2 until the end? The rationale behind this is explained in a detailed manner: Accessing a resource that hasn't been loaded is a logic error, i.e. a bug (that can be tracked down in Debug mode). You can't meaningfully react to such bugs at runtime, because they should never have occured in the first place.
-
Yes I did and I can understand your reasoning. But you justify the design choice with an assumption: The logic error will (or should be) tracked down in debug mode. In reality though (especially with large projects) you can not and will not track down all such bugs prior to release. So in the end users might be confronted with crashing software instead of just default or missing resources.
-
Following your argument, assertions would be generally pointless, since every bug can eventually occur in Release mode.
The problem with using exceptions is that you can't do anything meaningful at that time. As it's not a runtime but rather a logic error, you don't know what went wrong, and as a result, everything you do to react to it can make things even worse. From that time point, the application state is corrupt.
Keep also in mind that ResourceHolder::get() is not the place to say "missing resources" (since they must have been loaded in advance, by design); this check was performed earlier in load(), and covered with an exception.
-
Following your argument, assertions would be generally pointless, since every bug can eventually occur in Release mode.
If you use them as an error handling tool only, then yes. But I view assertions more of a tool designed to help the software engineer to track down bugs, rather than handling them.
The problem with using exceptions is that you can't do anything meaningful at that time. As it's not a runtime but rather a logic error, you don't know what went wrong, and as a result, everything you do to react to it can make things even worse. From that time point, the application state is corrupt.
Keep also in mind that ResourceHolder::get() is not the place to say "missing resources" (since they must have been loaded in advance, by design); this check was performed earlier in load(), and covered with an exception.
No, they must not have been loaded, they should have been loaded. Let's assume we're dealing with a large game. Let's also assume that for some reason a load call to a resource has never been made (thus an exception could never have been thrown). May it be because someone accidently deleted the load call or it was never there to begin with. It doesn't matter why. It only matters that it is missing.
Of course an assert can help in debug mode to track down that error, but only if that special part of the game is being tested. And keep in mind that it's a big game. So chances are that it might not be tested at all.
Naturally this a constructed case. But one that can actually happen. In this case the design choice can lead to a crash for the end user. And that is something you should avoid at all costs.
-
If you use them as an error handling tool only, then yes. But I view assertions more of a tool designed to help the software engineer to track down bugs, rather than handling them.
That's exactly how I see it. You technically can't handle bugs with assertions, the latter exist only for debugging and to alert the developer early of mistakes.
No, they must not have been loaded, they should have been loaded. Let's assume we're dealing with a large game. Let's also assume that for some reason a load call to a resource has never been made (thus an exception could never have been thrown).
I completely understand your point of view, but where do you draw the border? Do you always call std::vector::at() instead of operator[] because the index might be wrong? Do you check all divisors for zero even if you're sure the situation can't allow this? If not, why not? Such bugs might as well survive the tests and lead to crashes. This applies to tons of situations. It's also a bit a philosophical question, for example in Java exceptions are everywhere (to the point where it becomes annoying).
-
I just started the book and gone through the first three chapters. And I must say it is amazing. Even after over a year of hobbyist game development I learned much out of it. I'm really looking forward to the rest of the book. Amazing Work. Just wanted to say thanks for this work ;)
-
In Chapter 3 on page 59 it says "The window class internally calls our draw() function. No other classes need access to it, so we can make it private."
I got a little confused by this so I looked at class declaration for sf::Drawable and I noticed that it is friends with sf::RenderTarget. Is this why the window class is allowed to call our private draw() method? I have never used friends before so I'm just trying to make some sense out of this.
e: vvv Okay, thank you.
-
Is this why the window class is allowed to call our private draw() method?
Yes, friend classes are allow to access the private and protected fields of the class. It's not often used and should be only used in rare cases (e.g. in this case).
AlexAUT
-
I just finished chapter 7, and my missiles are behaving weirdly. They only appear if an enemy is on the screen- if there are no enemies, a missile is "expended" (the missile total goes down by 1), but no graphic is put on the screen. No missile goes firing off. If an enemy is on the screen, the missile jumps forward super fast ( either that, or it appears at the same y coordinate as the enemy, but with my x coordinate.) It is just suddenly at the same height as the enemy, but as far over in the x direction as I am. If I am directly below the enemy, it is instantly dead. If I am to the side and below the enemy, the missile jumps to the enemy's height and slowly turns until it is facing the enemy and tries to slowly move to the enemy. It usually fails.
Is anyone else getting this behavior? I wasn't able to get the CMake to work for me, so I haven't yet tried running the github files, but I have checked over my work carefully. I have even copy and pasted the contests of Aircraft.hpp, Aircraft.cpp, World.hpp, World.cpp, Projectile.hpp, Projectile.cpp, Entity.hpp, and Entity.cpp, just to be sure (those seemed to be the ones that might be effecting the missiles). If no one else is getting that behavior, any idea as to where to look to fix it in my code? I've been scratching my head over it all evening. Any insight you have would be greatly appreciated, and thanks in advance!
-
Not entirely sure this is the best place to ask, but I will anyway to start.
SFML looks great from what I can tell, and would love to start with this, as I've made a decision to get into game programming. It was probably 8 or 9 years ago I last used C++, and it was at a basic level. So I decided to start over.
This book looks to be a good start:
http://www.amazon.com/Beginning-C-Through-Game-Programming/dp/1435457420
My question is, could I go from that book, directly to the "SFML Game Development" book. If not, does anyone have any suggestions for books in between?
Thanks so much,
H
-
I can't say anything about that book in particular, but you may want to check out the following list. ;)
http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)
These are known to be good books.
-
@zsbzsb, awesome thanks! :D Much appreciated.
H
-
Is anyone else getting this behavior? I wasn't able to get the CMake to work for me, so I haven't yet tried running the github files, but I have checked over my work carefully.
You're the first to report this, so it's probably an issue with your build. But you need CMake for both the GitHub and original files, so how did you build it?
If I were you, I would try to get CMake running, I don't think it makes sense to search for bugs when it might be a simple configuration problem. Have you read the ReadMe.txt on GitHub? What doesn't work?
My question is, could I go from that book, directly to the "SFML Game Development" book.
It's a very good idea to have a look at advanced C++ books before starting with game development. A mistake that a lot of game developers make is underestimating the complexity of C++ and the importance of modern idioms and clean, structured code. Books like Effective C++ or Exceptional C++ address this issue, and there might even be updated versions for C++11.
-
You're the first to report this, so it's probably an issue with your build. But you need CMake for both the GitHub and original files, so how did you build it?
If I were you, I would try to get CMake running, I don't think it makes sense to search for bugs when it might be a simple configuration problem. Have you read the ReadMe.txt on GitHub? What doesn't work?
Thanks for the quick reply! I did read the ReadMe.txt, and followed it. I am using Visual Studio 2012 Express (Visual Studio 11), so I chose that as my compiler, found the SFML directory, chose static, and generated. When I try to run the release build, I get the error shown in the attachment. "Unable to start the program 'C:\<filepath>\07_Gameplay\Source\Release\ALL_BUILD'. The system cannot find the file specified."
Any ideas?
I built my project originally by creating a new project in Visual Studio 11 so I could get practice linking SFML and coding the project myself. To make sure I got the code correct, I would open up the code I downloaded from the github and compare across.
I've really been enjoying the book, by the way!
-
As stated in the ReadMe.txt (https://github.com/SFML/SFML-Game-Development-Book/blob/master/ReadMe.txt#L61), you have to build the INSTALL project. You're not supposed to run the game directly from the Visual Studio solution.
-
That fixed it! Not sure how I missed that. Now I know there is a problem with my code somewhere, and I will track it down. Thanks!
-
My question is, could I go from that book, directly to the "SFML Game Development" book.
It's a very good idea to have a look at advanced C++ books before starting with game development. A mistake that a lot of game developers make is underestimating the complexity of C++ and the importance of modern idioms and clean, structured code. Books like Effective C++ or Exceptional C++ address this issue, and there might even be updated versions for C++11.
[/quote]
@Nexus, thanks! I will definitely read up with these books as well.
Cheers,
H
-
Hi there,
I am currently at chapter 7 and I am having a problem...
I've already implemented the spawning enemies and their movements, along with the HP display.
Now I am at the projectiles part, and they are not being created...
At this point, the game should be firing bullets and missiles (without homing feature).
The fire() method is being called by the player and the enemies, and the flag is changing.
When the flag is active, the mFireCommand created at the Aircraft Constructor is being pushed in the CommandQueue in the checkProjectileLaunch() method.
Analogous with the launchMissile() method.
But while debugging I've noticed, the createBullets() and createProjectile() methods are never executed, so no Projectile is being created.
What could be the problem? I followed the code from GitHub, must have missed something, but I've been checking and rechecking for hours and couldn't find whats wrong :/
Any hints?
Everything else is working as espected, and the application compiles just fine.
// Edit
As i tought, it was something to do with the Command delivery to the SceneNode by its Category...
but i was looking at the wrong place all the time, rechecking the Categories of the Entities.
I spent 3h+ to find out that i was missing this line in the World::buildScene()
Category::Type category = (i == Air) ? Category::SceneAirLayer : Category::None;
Now it is working o/
// New edit
Just finished Chapter 7... it was a tough one ;)
But I am really excited with this book, SFML and game development.
It is the first time I have the feeling that I'm programming a game that is not so hardcoded and coupled.
The simple, yet enlightener architecture provided is perfect for newcomers to the game development area who likes to program and don't want to learn how to use a game engine before creating something simple and concise.
-
Hello,
Thanks for this awesome book
Question to authors:
How many years of experience you guys have ?
Did you design the all SceneNode/Game system yourself or you get inspired from other existing structures ?
I just can't imagine a similar structure myself, I've always have to copy your code in all my games... :(
sorry for my english
-
Of course we did not invent everything anew. A lot of concepts are common practice in game development, for example the scene graphs. Others such as the command system are less widespread. It takes some experience to develop your own ideas and designs; I think the best way is to experiment as much as possible and to question existing approaches, instead of blindly adopting them. When you're aware of the advantages and disadvantages of a certain technique, you'll also be able to look for alternatives with different trade-offs.
I have been working with SFML for 6 years now, and with C++ a bit longer.
-
We were trying to give a broad view of structures and patterns that you use and have a kind of exercise to use them. Like Nexus said, instead of just blindly adopting something we showed the strengths and weaknesses of everything.
You don't have to imagine a similar structure, there is no need to reinvent the wheel when it comes to stuff like this. Most often if you conform with a design pattern or similar the code will end up much better and cleaner.
I have been using SFML since I went to Highschool, so I guess that is about 6 years as well for me I think. C++ for much, much longer. Though I have to honest to say that Nexus skill in the new standards of C++11 were completely new to me and I loved that he actually pushed forward that we used that because I learned so much.
-
Nexus, you mentioned that the command system approach is less common. I have been wondering why you chose that approach over a more conventional approach, like an event system.
The main difference I see is the command system couples the event with the action. Whereas an event system would simply broadcast an event and let the game components handle them. In this regard the event system seems more flexible. Also, the command system is reliant on the scene graph.
Could you explain why you chose this system? What advantages do you see?
-
I'm not Nexus or any other author of the book, however in a general context, I can say, that the command system matched the created game better, than the general purpose event system. Which is one of the more important lessons to learn when creating games. Write code that fits your game needs. Don't just write code, because it's more generic or because everyone seems to include that feature. ;)
-
A command is more powerful than an event that holds only state and no functionality. You can simulate a classical event system using the command system, but not vice versa:
Command c;
c.category = ...;
c.action = [myEvent] (SceneNode& node, sf::Time) { node.handleEvent(myEvent); };
A difference is that the functionality is defined on the caller side rather than on the entity side. In this respect, commands are similar to direct function calls, but delayed and without knowledge of the receipents. Entities don't need to be prepared to handle a certain event correctly, the functionality can be implemented unintrusively using the public API of each entity. On the other side, this can be a drawback if you know absolutely nothing about the entities or require different reactions depending on the entity type. With commands, you don't have explicit case differentiations (switch statement), and there is no need to downcast events or their attributes. Furthermore, lambda expressions make it possible to take into account the context of the caller, and transport information back to it, without widening the caller's public API (for example, the EmitterNode and ParticleNode are connected in this way).
The book was also a good opportunity to introduce design choices that are not seen in every game. People will eventually learn different approaches, and can choose the one that best fits their needs.
-
I couldn't wait to get this book and bought the kindle edition. It is ok on the kindle, but I'm going to buy the hard copy when I can because I like to make notes. This is a great book that I am enjoying reading!
-
I couldn't wait to get this book and bought the kindle edition. It is ok on the kindle, but I'm going to buy the hard copy when I can because I like to make notes. This is a great book that I am enjoying reading!
Love to hear that you enjoyed it :)
-
Hey guys, I've been a lurker on this forum for some time now and just decided to join. I bought this book (hard copy) a little over a month ago and I have to say that it's been extremely useful and fun for me to go through. I just completed chapter 6 last night and am moving on to chapter 7 as of right now!
So thanks a lot for all of your hard work and time, it's very much appreciated :D.
-
I am going to get one soon, thanks or sharing..
-
Just want to make sure I'm not re-inventing the wheel here - has anyone else already ported the book samples to SFML.Net yet?
-
Just want to make sure I'm not re-inventing the wheel here - has anyone else already ported the book samples to SFML.Net yet?
Not that I am aware of.
-
I was just looking over the implementation of the ResourceHolder class again yesterday and recognized that ResourceIdentifiers.hpp uses enums nested in namespaces. I think the main purpose of this would be to "emulate" strongly typed enums (as of c++ enums are not strongly typed) so that no name conflicts arise.
C++11 offers enum classes which serve the purpose of strongly typed enums, so that one is enforced to use the strong name of an enum member.
So my question is, could the following code
namespace Textures
{
enum ID
{
Eagle,
Raptor,
Desert,
};
}
be rewritten to
enum class TextureID
{
Eagle,
Raptor,
Desert,
};
to accomplish the same goal? One must then reference to a member of this enum class via TextureID::Eagle instead of Texture::Eagle.
I don't want to do this just for the features sake, but to eliminate the additional namespace, because I think it's a not intended use for a namespace, and an enum class is a real type compared to a classical enum.
I think this is a worthwhile refactor, but would like to here more expert opinions on this.
Thanks in advance.
-
The book introduces strongly typed enums and mentions that they are not used because of compatibility with more compilers (page 37). So this choice is intended :)
The namespace around enums was a C++98 idiom to introduce scope. It's quite nice in my opinion, but not really necessary anymore with enum struct/enum class.
-
Heck, completely missed the part on strongly typed enum's in your book, should read more carefully and browse code less.
OK, question answered, my next implementation will make use of enum classes. ;)
But with that the next question arises:
The command system uses an enum for the receiver categories, where only one bit is set per enum member. The purpose is clear to construct compound categories via &-operator and to check compound categories via |-operator. I know I can contruct such a enum class with bitwise members, but do the bitwise operators still function the same way as with normal enums?
-
We don't use enum to combine the flags, Command::category is of type unsigned int. Only the single flags are enums.
As far as I know, you can't combine strongly typed enums with binary operators because they don't support implicit conversion to integral types. So you'd have to cast the values, or overload the operators.
You should however not try to store the results of flag combinations in enum types, since enums are intended to provide a small finite set of possible values, i.e. the enumerators. Either use unsigned int as we do, or think about a dedicated type-safe Flag<Enum> class template.
-
Overloaded bitwise operators can return bool (which is presumably what you want to use them as?).
-
Yeah overloading bitwise operators seems like a good idea. I will put it on the "to-research"-list and will come back later to it. For now I stick with storing categories as unsigned int as in the book, because it's a very easy and pragmatic implementation.
Thanks for the answers so far
Cheers!
-
Is the source code from the book applying all the principles of SOLID design? Namely what is found here: http://en.wikipedia.org/wiki/Solid_%28object-oriented_design%29 (http://en.wikipedia.org/wiki/Solid_%28object-oriented_design%29).
I have not checked myself because I am not skilled enough. Examples of what could be such designs are the scene graph and the command system, but it is just a guess.
-
The code is thoughtfully designed, if that's what you're asking. Whether it fully commits to SOLID principles or not is besides the point; in some cases it's probably not even relevant (after all, it is a demonstration project, not an extensible framework on which future titles will be built).
-
The question is: What does it matter to you, if you can't even verify it yourself.
Besides that principals are there to give a good orientation and should not be forced on to everything. Use it where it makes sense, adjust it where needed. ;)
-
I have just finished the book, so here's a small review of it.
I liked the relaxed nature of the text. There were times when a sentence was convoluted, ill formed, or didn't sound like natural English, but it was OK in general. The reason I liked the tone of the book may be because the previous book I read was by Stroustrup, so I guess just about anything feels approachable in comparison.
What I disliked most was the ordering of how different concepts are introduced. I concede to being a programming newbie, and that it's possible the authors had good reasons (which I don't understand) for structuring the book like they did, but mixing the game design with the game engine design was a mistake in my opinion. What the book should have been like, is to build the pure engine in the first chapters without any airplanes or sprites, and in the latter part of the book create a game on top of the finished engine.
This approach would have left all the chapters much cleaner, and probably shorter. Instead of introducing the SFML concepts mixed in with the game code, mixed in with game engine logic, the author would have been free to to describe either one in focus and greater detail. Of course the downside is for the reader to not get to the fun stuff immediately, but I'm arguing that the gain in terms of clarity and succinctness would have been more than well enough worth that trade.
As a bonus, it would let the reader start experimenting with their own game quickly, instead of having to either start over, or to spend the effort of cutting out all the airplanes from their code if they want to make some other kind of game.
That was my main gripe. As a whole I really did like it, and I'm glad to have been introduced to so many useful mechanics, such as the scene graph and command system, although I'm still somewhat confused about lambdas and some other things.
It's a pretty solid introduction for someone wanting to get into C++ game dev, and for now I will recommend it if the topic comes up.
Big thanks to the authors for this book.
-
t it's possible the authors had good reasons (which I don't understand) for structuring the book like they did
create a game on top of the finished engine.
http://scientificninja.com/blog/write-games-not-engines
-
The article may have a point about someone who just wants to make a very small game. I would agree, if I'm making flappy bird then I will not bother defining a core framework (i.e an engine) before starting on the game logic.
But in anything more complex, I would definitely start by defining some kind of engine first. You may not have to do that, and if you are an expert programmer then perhaps you won't make any fundamental mistakes along the way, mistakes which would force you waste time refactoring deep parts of the game.
But that's all when just talking about someone simply making a game.
However, the book is something else than a diary of an indie developer, it's actually trying to teach something, and my point is that it would have done a better job of doing so by separating the game from the game engine.
-
It's just as true of big games. You can't write a useful game engine without a very clear concept of what the actual game is going to be. Otherwise you simply don't know what the engine needs to do.
Theoretically you could try to write an engine that supports every kind of game every dreamt up by anyone, but we've all seen what happens when you try that (http://en.sfml-dev.org/forums/index.php?topic=13779.0). And even if you succeeded, it wouldn't be anywhere near as good as an engine designed for the particular kind of game you actually want.
What the book could potentially have done is say "we'll be making an engine for a 2D platformer" and then just assume everyone knows what a 2D platformer needs to do. But, I think the target audience of the book is people who are new to game programming, and do not necessarily know on a technical level what a 2D platformer will and won't need to do.
-
I'll be sure to get myself a copy as well.
-
The question is: What does it matter to you, if you can't even verify it yourself.
Besides that principals are there to give a good orientation and should not be forced on to everything. Use it where it makes sense, adjust it where needed. ;)
It could matter to me because I am interested in applying good design from the start. If I am told that, yes, this principle and that principle are applied in the book, in this concept and that concept, I know I can then look up myself. The good thing about it is that we have both clear explanations from the book and access to the source code for implementation details. So I'd be able to learn about such advanced topics more easily.
BTW my goal is not to copy and paste source code into my own project. I want to understand topics and put what I can get from that into my own code.
-
It could matter to me because I am interested in applying good design from the start. If I am told that, yes, this principle and that principle are applied in the book, in this concept and that concept, I know I can then look up myself.
The problem with this is that most of these principles are pretty subjective. One programmer might find a class too granular while another might argue that it perfectly fits the definition of SRP.
-
Thank you for the feedback.
Concerning code design: we did put a large focus on OOP principles such as modularity, abstraction and encapsulation. We even emphasized the importance of them in the first chapter. At the same time, we tried to keep things simple, so you will find a quite pragmatic application of these principles. We have not intended to provide a totally abstract code base that can serve for any possible game, but rather to show solutions to many common problems in game development, and in particular applied to our game. Design decisions are regularly discussed with respect to their advantages and disadvantages.
Concerning separation of engine and game: there are several reasons why we have not structured the book like this. One is mentioned in the last paragraph: we tried to be pragmatic. Since the book is about development of a game and not an engine, we have never intended to provide a framework to fit all purposes. Nevertheless, several techniques (e.g. scene graph, commands, resource management) are abstract and generic enough to be applied elsewhere. Another important point is that a book should be interesting to read, and writing half of the chapters about development of an abstract engine without showing the use cases isn't. Keep also in mind the audience: SFML Game Development requires no previous knowledge of game development, a lot of readers are complete newcomers. In my opinion, the first thing one should learn in game development is definitely not writing an engine. Doing so would require considerable practical experience, without which will be difficult to understand all the decisions behind it.
-
What is required knowledge of c++ to read this?
I know the basics of c++ like pointers reference but dont have an practical experience on it.
Is my knowledge enough?
-
An intermediate level of C++ is required. If concepts like classes, OOP, templates, exceptions, function objects, memory management or the STL are new to you, I recommend reading a good C++ book (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) (preferably one with C++11) in advance.
If you have already basic understanding of the programming language, it is also possible to learn more advanced C++ concepts in parallel to our book, however it requires some discipline. You shouldn't worry too much about the new standard C++11 though, the book was written with C++98 programmers in mind -- we quickly explain every new feature we use, and readers are free to have a deeper look at them on their own.
To sum up, it really depends on how much you already know and the way you learn new things, but I'd say good C++ knowledge (and some practical experience) is definitely an advantage.
What you can also do is have a look at some parts of the source code (https://github.com/SFML/SFML-Game-Development-Book) and see if you understand it.
-
So far I am reading c++ primer 5th edition. But that book is like a thousand page and even though i have some programming experience in java i dont have a single practical experience in c++.
What i know is functions, pointers, reference, OOP and ofcourse classes
What i dont know, memory management although i know about something about heap and stack, STL(is vector, arrays, string, character part of STL?), and templates.
Do you think i can still read the book?
-
I think it should be possible, even if difficult. You will recognize when things are unclear -- in that case, just don't hesitate to read up the corresponding parts in the C++ Primer.
By the way, this book is a thousand pages because C++ is a very complex language, and all the books (and tutorials) claiming to teach the language within a few weeks are blatantly lying. You don't need to know every corner of the language in order to develop games, but it's important that you understand the core principles and philosophies.
Especially when you come from a Java background, you have to be very careful to not adopt Java techniques, when the C++ equivalents look completely different. The languages look similar on the surface, but they're not at all. Some notable examples:
- In Java, the main abstraction feature is the class, i.e. object-oriented programming. Everything is modeled with hierarchies of classes and interfaces. C++ provides many additional abstraction mechanisms: templates (which are far more powerful than generics), global functions, function objects (instead of callback interfaces), typedef, namespace + ADL. A bigger focus is laid on generic and functional programming paradigms.
- C++ uses value semantics, reference semantics (as in Java) have to be stated explicitly. This implies that objects have a defined state (not null) during their lifetime. It also makes ownership explicit, whereas Java references are shared among their users. In modern C++, you rarely allocate objects with new, at least not without packing them into a smart pointer. The default way to create objects is by using the automatic storage ("stack"), dynamically allocated objects are encapsulated. A consequence of this is that you have to be aware when and for how long your objects live, they won't be automatically kept alive as long as you use them.
- C++ provides deterministic destructors, which allows for strict resource management in the form of RAII. That is, all the times where Java forces you to call close(), C++ can release resources automatically. RAII is a more advanced form of the try-with-resources statement, that spans not only local variables, but any scope.
- Exceptions are less prominent than in Java. C++ provides no checked exceptions, and the general approach is to let RAII handle resource deallocation and rollback semantics, allowing you to have much fewer try/catch statements.
- C++'s philosophy is "zero abstraction overhead", where Java makes operations as safe and context-aware as possible. One implication is that a lot of operations in C++ lead to undefined behavior if you use them incorrectly (e.g. index out of bounds), in order to not waste performance on checks that are useless in correct code. In general, logic errors are rather caught by assertions (debugging feature) than exceptions. Classes and functions in C++ don't exist at runtime anymore, they're a pure compile-time abstraction mechanism; Java keeps records of them for reflection.
-
Thanks. I might give it shot. But ah is this thread good for asking question related to c++? like for example when the book uses some technique that is way beyond my knowledge?
-
But ah is this thread good for asking question related to c++?
Not really. In fact, this whole forum is not, there are better places for language-specific questions (C++ forums or StackOverflow, for example).
If you have semantic questions related to the book, i.e. you do understand the C++ code, but don't know why we made a certain design decision, you can of course ask here.
-
Ow okay.. Thanks by the way..
One last thing. Why no kindle edition? :(
-
There is one... (http://www.amazon.com/SFML-Game-Development-Artur-Moreira-ebook/dp/B00DL0CFHC)
-
Hey Guys,
I have a problem with the code from chapter 7. I followed the book correctly but I cannot compile the Player-Class because of the following error:
1> Player.cpp
1>c:\development\downloads\sfml game development\07_gameplay\include\book\command.hpp(33): error C3848: expression having type 'const std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Aircraft::* )(void),void,Aircraft,>,std::_Ph<1> &>' would lose some const-volatile qualifiers in order to call 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Aircraft::* )(void),void,Aircraft,>,std::_Ph<1> &>::operator ()<GameObject&,sf::Time&>(GameObject &,sf::Time &)'
1> with
1> [
1> GameObject=Aircraft
1> ]
I use VC2013 with Update 2 to compile this.
What I figured out until now, is that if I comment out the lines 111 and 112 from Player.cpp
mActionBinding[Fire].action = derivedAction<Aircraft>(std::bind(&Aircraft::fire, _1));
mActionBinding[LaunchMissile].action = derivedAction<Aircraft>(std::bind(&Aircraft::launchMissile, _1));
it compiles. The problem lies somehow in the std::bind.
Also in DataTables.cpp I get the following error for the std::bind-statements:
data[Pickup::HealthRefill].texture = Textures::HealthRefill;
data[Pickup::HealthRefill].action = std::bind(&Aircraft::repair, _1, 25);
data[Pickup::MissileRefill].texture = Textures::MissileRefill;
data[Pickup::MissileRefill].action = std::bind(&Aircraft::collectMissiles, _1, 3);
data[Pickup::FireSpread].texture = Textures::FireSpread;
data[Pickup::FireSpread].action = std::bind(&Aircraft::increaseSpread, _1);
data[Pickup::FireRate].texture = Textures::FireRate;
data[Pickup::FireRate].action = std::bind(&Aircraft::increaseFireRate, _1);
1> DataTables.cpp
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(1241): error C2100: illegal indirection
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(1149) : see reference to function template instantiation '_Rx std::_Pmf_wrap<void (__thiscall Entity::* )(int),_Rx,Entity,int>::operator ()<Aircraft>(_Wrapper &,int) const' being compiled
1> with
1> [
1> _Rx=void
1> , _Wrapper=Aircraft
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(1149) : see reference to function template instantiation '_Rx std::_Pmf_wrap<void (__thiscall Entity::* )(int),_Rx,Entity,int>::operator ()<Aircraft>(_Wrapper &,int) const' being compiled
1> with
1> [
1> _Rx=void
1> , _Wrapper=Aircraft
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(1137) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>::_Do_call<Aircraft,0,1>(std::tuple<Aircraft &>,std::_Arg_idx<0,1>)' being compiled
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(1137) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>::_Do_call<Aircraft,0,1>(std::tuple<Aircraft &>,std::_Arg_idx<0,1>)' being compiled
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xrefwrap(283) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>::operator ()<Aircraft&>(Aircraft &)' being compiled
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xrefwrap(283) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>::operator ()<Aircraft&>(Aircraft &)' being compiled
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(228) : see reference to function template instantiation '_Ret std::_Callable_obj<std::_Bind<true,_Ret,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>,false>::_ApplyX<_Rx,Aircraft&>(Aircraft &)' being compiled
1> with
1> [
1> _Ret=void
1> , _Rx=void
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(228) : see reference to function template instantiation '_Ret std::_Callable_obj<std::_Bind<true,_Ret,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>,false>::_ApplyX<_Rx,Aircraft&>(Aircraft &)' being compiled
1> with
1> [
1> _Ret=void
1> , _Rx=void
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(226) : while compiling class template member function 'void std::_Func_impl<_MyWrapper,_Alloc,_Ret,Aircraft &>::_Do_call(Aircraft &)'
1> with
1> [
1> _Alloc=std::allocator<std::_Func_class<void,Aircraft &>>
1> , _Ret=void
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(495) : see reference to class template instantiation 'std::_Func_impl<_MyWrapper,_Alloc,_Ret,Aircraft &>' being compiled
1> with
1> [
1> _Alloc=std::allocator<std::_Func_class<void,Aircraft &>>
1> , _Ret=void
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(396) : see reference to function template instantiation 'void std::_Func_class<_Ret,Aircraft &>::_Do_alloc<_Myimpl,_Ty,_Alloc>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>
1> , _Alloc=std::allocator<std::_Func_class<void,Aircraft &>>
1> , _Fty=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(396) : see reference to function template instantiation 'void std::_Func_class<_Ret,Aircraft &>::_Do_alloc<_Myimpl,_Ty,_Alloc>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>
1> , _Alloc=std::allocator<std::_Func_class<void,Aircraft &>>
1> , _Fty=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(385) : see reference to function template instantiation 'void std::_Func_class<_Ret,Aircraft &>::_Reset_alloc<_Ty,std::allocator<std::_Func_class<_Ret,Aircraft &>>>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>
1> , _Fty=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>
1> , _Alloc=std::allocator<std::_Func_class<void,Aircraft &>>
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(385) : see reference to function template instantiation 'void std::_Func_class<_Ret,Aircraft &>::_Reset_alloc<_Ty,std::allocator<std::_Func_class<_Ret,Aircraft &>>>(_Fty &&,_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>
1> , _Fty=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>
1> , _Alloc=std::allocator<std::_Func_class<void,Aircraft &>>
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(688) : see reference to function template instantiation 'void std::_Func_class<_Ret,Aircraft &>::_Reset<_Ty>(_Fty &&)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>
1> , _Fty=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(688) : see reference to function template instantiation 'void std::_Func_class<_Ret,Aircraft &>::_Reset<_Ty>(_Fty &&)' being compiled
1> with
1> [
1> _Ret=void
1> , _Ty=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>
1> , _Fty=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>
1> ]
1> c:\development\downloads\sfml game development\07_gameplay\source\datatables.cpp(64) : see reference to function template instantiation 'std::function<void (Aircraft &)> &std::function<void (Aircraft &)>::operator =<std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>>(_Fx &&)' being compiled
1> with
1> [
1> _Fx=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>
1> ]
1> c:\development\downloads\sfml game development\07_gameplay\source\datatables.cpp(64) : see reference to function template instantiation 'std::function<void (Aircraft &)> &std::function<void (Aircraft &)>::operator =<std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>>(_Fx &&)' being compiled
1> with
1> [
1> _Fx=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Entity::* )(int),void,Entity,int>,std::_Ph<1> &,int>
1> ]
When commenting out the lines with the std::bind, everything compiles fine.
I also tried the code from the official download, same problem. Haven't tried the github-code but will do so.
But maybe in the meantime anyone knows why this happens?
Thanks in advance
-
See here (http://en.sfml-dev.org/forums/index.php?topic=11992.msg85540#msg85540). The GitHub code (https://github.com/SFML/SFML-Game-Development-Book) should work.
-
Just found the compiler bug related to std::bind via Google. Tried the github-code, works fine. Thanks for clearing this so fast. ;)
Cheers!
-
I am experiencing lag down to 2 FPS when shooting a lot of bullets. This is the game's code on the last chapter straight from github. The game runs at a solid 60 fps then I start to get powerups that increase the number of bullets as well as the firerate. If I hold down the fire button and fill the screen with my bullets I sink down to 2 FPS. Anyone else experience such lag?
This is on an i5-3570K 4 core at 3.4ghz
8g RAM
NVIDIA GTX660TI
-
As mentioned in the book, the collision algorithm does not scale very well for many objects (that's also why proposed a range of possible extensions). But it seems strange that you're experiencing the lag in normal use, are you compiling in Debug mode or with other checks/debuggers enabled?
-
I tried the same tests with a release build and things seemed to stay at a consistent 60fps. I understand the implications of the current collision detection system as it does not scale very well. I however lack an understanding as to how a debug build could cause such a great performance hit compared to a release build. Any input would be great.
-
A debug build does not (usually) make any optimizations, and leaves all the debug information in the executable created, which leaves the computer doing more work for some instructions, thus slowing down execution of the application.
-
Thanks guys. It all make quite a bit of sense now. I appreciate it.
-
I bought the book and also took a look at the Gamestate Manager. I used a similar system up to now and have a question I couldn't find the answer to in the book: How do you pass information between the states? Consider for example that I have a menu state where I select a level. When I continue to the load level state, I still have to know, which level was chosen in the menu. Or for example a highscore state, where the score is sent to the web and compared with others - how does the highscore state know the score from the game state?
Is the State::Context where you would do this? I rather understood the Context as a collection of pointers to all the technical stuff in the background - not as a place where any game logic happens.
-
Is the State::Context where you would do this?
With our design, yes. In general, it would also be possible to pass that information to the constructor of the next state.
I rather understood the Context as a collection of pointers to all the technical stuff in the background - not as a place where any game logic happens.
These pointers are used to access data that persists across states, e.g. resources. You're right that the logic doesn't really happen in State::Context, as the class provides no functionality. You could do this similarly for highscore: store the data/functionality elsewhere, and just reference it in the context.
-
What is required knowledge of c++ to read this?
I know the basics of c++ like pointers reference but dont have an practical experience on it.
Is my knowledge enough?
-
I hope nobody is gonna sue me for quoting the book. ;)
C++ is a very powerful, but also very complex programming language; even after years one never stops learning. We expect you to understand the basic language features (variables, data types, functions, classes, polymorphism, pointers, and templates), as well as the most important parts of the standard library (strings, streams, and the STL). If you feel unsure, we recommend reading a good C++ book, before or in parallel to this book, since SFML and our code sometimes uses advanced techniques. Game development is a difficult topic on its own; it is very frustrating if you additionally have to fight C++. Even if it takes some time to reasonably learn the programming language, it is a good investment, since it will save you days of tedious debugging.
-
What is required knowledge of c++ to read this?
I know the basics of c++ like pointers reference but dont have an practical experience on it.
Is my knowledge enough?
I read the book. Based on my own experience, my candid answer to your question is: you need at least intermediate C++ to work through it. The book is not for beginning C++ programmers. So, um, your knowledge most likely isn't enough (mine wasn't, and I worked hard to catch up), and you'll feel lost.
If you don't have any practical experience, go and get it. Get a free IDE/compiler combo (e.g. VS Express Edition, Qt Creator), buy a good book and - I can't stress this enough - work through *ALL* exercises.
The book uses some C++11. The book briefly explains each new C++11 feature before using it, but (understandably so) not in depth; here are some C++11 references I found useful:
Ten C++11 Features Every C++ Developer Should Use (http://www.codeproject.com/Articles/570638/Ten-Cplusplus-Features-Every-Cplusplus-Developer)
The Biggest Changes in C++11 (and Why You Should Care) (http://blog.smartbear.com/c-plus-plus/the-biggest-changes-in-c11-and-why-you-should-care/)
C++11 Tutorial: Let Your Compiler Detect the Types of Your Objects Automatically (http://blog.smartbear.com/c-plus-plus/c11-tutorial-let-your-compiler-detect-the-types-of-your-objects-automatically/)
C++11 Tutorial: Lambda Expressions — The Nuts and Bolts of Functional Programming (http://blog.smartbear.com/c-plus-plus/c11-tutorial-lambda-expressions-the-nuts-and-bolts-of-functional-programming/)
Using C++11’s Smart Pointers (http://www.umich.edu/~eecs381/handouts/C++11_smart_ptrs.pdf)
Finally, the class and application design becomes increasingly sophisticated as you work through the chapters. I found it helpful to draw class diagrams to understand the relationships between classes.
-
I can't stress this enough - work through *ALL* exercises.
+1
I've seen so many students struggling mostly because they skip the exercises and jump directly to something too big for them. What Georger just said is really important if you want to succeed. Don't rush, take your time and go step by step.
Graphic programming is not that easy despite how cool it looks like. ;)
-
I am a newbie when it comes to c++ just started 3days ago and in the same time started using SFML.
can it still be worth getting this book despite im a total newb:P?
-
See the above comments. The book requires a good basis in C++.
In general you should also learn C++ with a good book (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list), before using SFML.
-
See the above comments. The book required a good basis in C++.
In general you should also learn C++ with a good book (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list), before using SFML.
c++ primer from the list in the link seems neat for a beginner book:)
-
I ran into a bug with the following function from utility.cpp.
void centerOrigin(sf::Text& text)
{
sf::FloatRect bounds = text.getLocalBounds();
text.setOrigin(std::floor(bounds.width / 2.f), std::floor(bounds.height / 2.f));
}
The left and top coordinates for sf::Text are not guaranteed to be zero. Corrected code:
void centerOrigin(sf::Text& text)
{
sf::FloatRect bounds = text.getLocalBounds();
text.setOrigin(std::floor(bounds.left + bounds.width / 2.f), std::floor(bounds.top + bounds.height / 2.f));
}
-
That's a good catch, thank you. I have to admit I'm a bit surprised that the local bounding rectangle doesn't start at the origin...
Out of interest, have you encountered this problem in a specific situation, where the text was wrongly positioned?
-
I have to admit I'm a bit surprised that the local bounding rectangle doesn't start at the origin...
The bounding rect is calculated from the geometry, so it usually has a small offset on Y. This is a common question/issue on the forum ;)
-
Out of interest, have you encountered this problem in a specific situation, where the text was wrongly positioned?
It is subtle, but I have been noticing it everywhere I use text. You can see it in the book's project. The text is a bit lower than it should be in the screenshot.
-
The use of unique_ptr is a bad choice for SceneNodes, why are you using unique_ptr and then create other pointers using get() in your World class ? You should use shared_ptr if you want to share the memory.
-
The use of unique_ptr is a bad choice for SceneNodes, why are you using unique_ptr and then create other pointers using get() in your World class ? You should use shared_ptr if you want to share the memory.
Not necessary. The fact it's using a unique_ptr indicates that the variable is owned by only one resource. It is acceptable to have a naked pointer coming from get() that connects to the unique_ptr instance. That means it is not the responsibility of whoever uses that pointer to delete it. He doesn't own it. The SceneNode is in fact owned by only one. So the use of unique_ptr is good.
-
But the SceneNodes are not owned by one ressource, World class also owns SceneNodes who were intended to be owned by only one ressource.
The use of unique_ptr in this case is only complicating things, it would be much simpler and senseful with shared_ptrs.
-
The use of unique_ptr is a bad choice for SceneNodes, why are you using unique_ptr and then create other pointers using get() in your World class ?
Because it describes the ownership semantics best. It doesn't matter whether there are additional pointers or references to the object stored in the unique_ptr, as long as its validity can be ensured. It's like having pointers or references to any other object.
But the SceneNodes are not owned by one ressource, World class also owns SceneNodes who were intended to be owned by only one ressource.
Not "also". The World class is the sole owner of the scene graph (that is, the root scene node). Every scene node owns its children. It's as simple as that.
The other references and pointers do not express an ownership relation, but a pure indirection. Ownership means being responsible of an object's lifetime. This is clearly not the case for the raw pointers that point to dedicated scene nodes, because the world is not supposed to destroy them through those pointers. The scene graph will take care of their destruction by itself.
The use of unique_ptr in this case is only complicating things, it would be much simpler and senseful with shared_ptrs.
The opposite is the case. shared_ptr looks easy to use, but it tends to make people think less about ownership semantics. Instead of having a clear owner, you distribute ownership over multiple instances in the hope that you needn't care about who cleans up. Don't use shared pointers as a GC replacement; it has been conceived for cases where you have shared ownership -- i.e. multiple instances that own one object and you cannot determine a single one which is responsible of it. Keep in mind that shared_ptr not only comes with some overhead, but it also enables memory leaks through cyclic references.
To understand our design choices better, I recommend reading this post (http://en.sfml-dev.org/forums/index.php?topic=13902.msg97463#msg97463).
-
I'm trying to implement text box to do a chat in multiplayer mode. How would you do it? I know about TextEntered event, but what is the best way to differentiate between normal key presses and text input?
This is how I would do it. Is it correct way to do that?
GameState::handleEvent(const sf::Event& event)
{
if (!gui.isTextCapturing()) {
FOREACH(auto& pair, mPlayers)
pair.second->handleEvent(event, commands);
}
gui.handleEvent(event);
}
and isTextCapturing is set by pressing some button.
-
Yes, I'd also switch between a play and a chat mode, triggered by a certain key (Return?).
Are you sure you're not missing other important events like this? You should probably only filter key pressed/released events.
By the way, you can use code tags like this: [code=cpp] [/code] :)
-
I'd call myself an intermediate C++ developer (and completely new to game development), and as such feel like the book was specifically aimed at me. I most certainly learned a lot of useful patterns reading it, thank you. I have some questions, some which were already asked and answered in this thread (such as why use heap allocation in ResourceHolder), and would greatly appreciate any replies:
1. What are the most obvious optimizations one might do? In my project, there is no collision detection, but rather it is about entities moving randomly on a map. As it stands, I can draw of the order of 10000 animated entities before I take a frame rate hit. I don't plan on ever having this many entities on screen at once, but might have a comparable number in the in-game world. Do you suppose the lowered performance is due to the many draws and that optimizations related to drawing i.e. culling would be the way to go? Alternatively, might this be because of the SceneGraph traversals and the scattered form of the data, meaning that I would need to group the relevant data better for less cache misses? Obviously I could try to parallelize the code, too, which should result in speed improvements.
2. What is a sensible way to control Views? The book implementation only has a View in World and player input through CommandQueue does not, and cannot, affect this. Does it make sense to have Views in SceneNodes and how could I, say, draw a dynamical GUI with buttons for the player to click, or have the player input control the scrolling of the view of the World. I understand how to technically use views and have an ugly hack in place, but I am asking if someone might be able to think of some nice organization for the code.
I have other questions (mostly about code organization), but I think these will do for now. Finally, I should say that I did not read the book cover-to-cover, but skimmed some parts, so I apologize if some of these were already discussed therein.
-
Do you suppose the lowered performance is due to the many draws and that optimizations related to drawing i.e. culling would be the way to go? Alternatively, might this be because of the SceneGraph traversals and the scattered form of the data, meaning that I would need to group the relevant data better for less cache misses?
That's difficult to tell without measurements... I recommend using a profiler and see exactly where the bottlenecks are.
In general, too many draw calls to the graphics card can be mitigated by combining entities (sf::VertexArray), and contiguous arrays that store data and can be iterated in one pass improve cache efficiency (there can still be pointers/indices to the elements from elsewhere). But don't make your life more complicated if you don't need it, premature optimization is evil ;)
Obviously I could try to parallelize the code, too, which should result in speed improvements.
That's not obvious. In fact, I suggest to avoid multithreading unless you see a clear benefit (exploiting the full processing power) or a bare necessity (one thread blocks, other functionality must remain responsive). Multithreading brings a considerable amount of complexity to an application, which is not always worth bearing.
how could I, say, draw a dynamical GUI with buttons for the player to click, or have the player input control the scrolling of the view of the World
For the GUI, you could first draw the world's view as you know it from the book, and then switch to a default view (starting at the origin and using the window's size) where the GUI elements are drawn.
Otherwise, it depends a bit on what flexibility you need. Do you need picture-in-picture (e.g. a small part of the window drawing another scene) or minimaps? Split-screen? I would not handle the view inside a scene node, because the whole scene graph (i.e. the game's scene) is usually rendered at once, from one point of view.
-
Thank you for the reply and the useful suggestions (sf::VertexArray, should I ever need it).
For the GUI, you could first draw the world's view as you know it from the book, and then switch to a default view (starting at the origin and using the window's size) where the GUI elements are drawn.
Otherwise, it depends a bit on what flexibility you need. Do you need picture-in-picture (e.g. a small part of the window drawing another scene) or minimaps? Split-screen? I would not handle the view inside a scene node, because the whole scene graph (i.e. the game's scene) is usually rendered at once, from one point of view.
Right, switching between views is indeed what I had in mind, but I am unsure how to propagate the inputs to this elegantly. For example, suppose a rightclick ought to open a menu, or that in the airplane game, the user input could affect the scrolling speed of the world.
Currently, the user input flows through a CommandQueue, which only affects SceneNodes. I can, for example, build a separate queue for commands to view, but this doesn't strike me as good design. So, alternatively, I could have a pointer to a special SceneNode in World, like PlayerAircraft* mPlayer which, being a SceneNode, can read inputs through the CommandQueue. I could then in the World::update do something like if(mPlayer->isMenuOpen()) openMenu();.
I suppose the latter is in line with the book's implementation, but it somehow seems a bit circular and I am not really liking the idea that the entity would need to know about views and store data about it (such as the bool isMenuOpen() function).
Am I making any sense or am I completely off tracks here?
-
Are we talking about a heads-up display (HUD) that is overlaid while the game keeps running, or a separate menu? In the latter case, I'd use another state. The book treats this scenario with the example of a pause menu.
The former case could be a user interface to health, ammo, progress in the level, score, etc. Currently, the World class holds and moves the view; World::draw() applies it. If you have a additional UI to draw, you could reset the view after drawing the scene. About input: if you want to work with commands, the least intrusive method would probably be a scene node that catches specific commands to alter the view. This scene node itself does not change the view, but exposes the view's state that can be polled by the World class.
Keep in mind that it's just one way of doing things; as we mentioned in the beginning of the book, the framework we provide is meant as a starting point and not as the ultimate solution to every game. So, don't hesitate to experiment a bit. If you are already experienced in game development architecture, you can also have a look at entity-component-systems. Although they solve some problems nicely, they are rather complex. Designing them is not an easy task, and you tend to invest even more time into planning (and sometimes over-engineering)... It's all about trade-offs.
-
I'm using the structure of the book to make games, I already Programmed a Pacman.
I want to find nodes by "key" in scene_graph. I need it for scripting and program the quest system of an action rpg. My problem I think it's that I don't understand recursion, i'm not sure if I can return a node.
template<typename T>
T* findNode(std::string c_key)
{
if (c_key == key)
{
return (static_cast<T*>(this));
}
for (auto &itr : children)
{
itr->findNode<T>(c_key);
}
}
Then I call the function and it fails, I get the error typical when acceding to a method of an object pointing to null:
scene_graph->findNode<Enemy>("dog01")->getHp();
The problem it's the returning node because inside the find function the search works and I can get info. I feel like I'm not returng the value in the correct way.
If I check the info inside the find function for each entity it tells the info correctly.
if (c_key == key)
{
std::cout << "Info" << (static_cast<T*>(this))->getHp() << std::endl // Works for each enemy
return (static_cast<T*>(this));
}
-
This is a good example of something you could probably catch on your own if you used a debugger and stepped through the code.
I would assume the problem is that in the non-base case...
itr->findNode<T>(c_key);
...you find the value, then immediately throw it away instead of returning it to the caller. You probably want a "return" on that line.
-
Your compiler should also raise a warning, since not all code-paths end up with returning anything.
You have to take warnings serious and if you didn't get a warning, you should up your warning levels. ;)
-
I found the solution. Instead of returning the value in the recursive function I use an auxiliar node to store the value and returning it. If it's not found there is an assertion.
template <typename T>
T* getNode(std::string c_key)
{
SceneNode *aux_node = nullptr;
findNode(c_key, aux_node);
assert(aux_node != nullptr);
return static_cast<T*>(aux_node);
}
void SceneNode::findNode(std::string c_key, SceneNode *&aux)
{
if (c_key == this->getKey()) aux = this;
for (auto& itr : children) itr->findNode(c_key, aux);
}
Then I call the function:
scene_graph->getNode<Enemy>("Nosferatu")
-
I have been using the following methods from the book to check for collisions in my personal project.
void checkSceneCollision(SceneNode &sceneGraph, std::set<Pair> &collisionPairs);
void checkNodeCollision(SceneNode &node, std::set<Pair> &collisionPairs);
My scene graph is quite a bit larger than the scene graph used in the the book's game. However, in release my game still runs fine (200 fps), but in debug it has become nearly unresponsive ( < 1 fps). I can't use the debug mode currently.
I could toggle the size of the scene graph for the debug and release versions, but before I do that I want to understand why this has become necessary in my simple game.
I was curious if you had any insight into this? Thanks!
-
As you have discovered, the compilers optimizer has a huge impact on C++ performance.
If you are using a recent GCC as your compiler, then you can get a much better debug performance experience by using "-ggdb -Og" instead of "-ggdb -O0" when generating your debug builds. The "-Og" switch turns on all optimizations that don't inhibit debugging as opposed to "-O0" which turns off all optimizations.
-
Thanks Jesper. I am using Visual Studio. I am looking into disabling debug support for iterators, but I will need to recompile all the libraries I use.
Makes me wonder what all they have to do to get a triple A title to run in debug mode.
-
Makes me wonder what all they have to do to get a triple A title to run in debug mode.
Probably unit tests and split modules (i.e. only debug what you really have to). :)
And you can also attach a debugger just-in-time in case there's a crash happening. You don't have to let it run connected all the time. With higher editions of Visual Studio you also get a "variable history", so you can jump back in time before the crash happened and go step-by-step from there, etc.
-
In some cases it can also be necessary to debug optimized code. Fairly painful but not impossible.
-
one question about the codebase of the book is bugging me.
The SceneNode-Class is conceptually a base class for the most Entities in the Game. Thus many of its methods are virtual because its intended that other classes derive from it. So why isn't SceneNode's destructor set to virtual to ensure a complete deletion of the derived objects to prevent object slicing when its held by a SceneNode (smart)pointer?
-
The SceneNode destructor is virtual.
There's no need to declare it again because it is inherited from sf::Drawable.
-
oh now i see! That was the bit i was missing. Now everything makes sense again, thanks for the hint! :-)
-
Hi, I'm working through the book, currently at Chapter 5. Up to this point in the book, the game FPS stats are implemented as members of the Application class. After working through the State and StateStack code, it occurred to me that I could make the stats into a "DebugState" object, essentially the same as the MenuState, so that display of the stats can be toggled on and off with the "D" key.
I'd also like to show the Player Aircraft's coordinates on the DebugState layer. However, after the code reorganization with the State objects, the Aircraft object is now a private member of the World object, which is in turn a member of the GameState object, and not so easy to access from another State object:
class GameState : public State
{
...
private:
World mWorld;
}
class World : public sf::NonCopyable
{
public:
explicit World(sf::RenderWindow& window);
...
private:
Aircraft* mPlayerAircraft; <-- need to get x,y from this member
};
class Aircraft : public Entity {...}
class Entity : public SceneNode {...}
class SceneNode
{
public:
sf::Vector2f getWorldPosition() const; <-- method to get x,y
}
Perhaps I could move the World member from GameState into Application, then add it to the State::Context? It would then be accessible to all States, in the same way as the Player object:
class Application
{
...
private:
sf::RenderWindow mWindow;
TextureHolder mTextures;
FontHolder mFonts;
Player mPlayer;
World mWorld;
StateStack mStateStack;
};
// Constructor
Application::Application()
: mWindow(sf::VideoMode(640,480), "States", sf::Style::Close)
, mTextures()
, mFonts()
, mPlayer()
, mWorld(mWindow)
, mStateStack(State::Context(mWindow, mTextures, mFonts, mPlayer, mWorld))
{
...
}
Any ideas or hints are welcome!
-
Perhaps I could move the World member from GameState into Application, then add it to the State::Context?
That doesn't make sense from a semantic standpoint. A world exists only during the game, i.e. within the game state.
Don't just choose the seemingly simplest approach, it will make your whole design more complex if the lifetime of all the world and game objects is extended to the application duration. Furthermore, there's no reason why the application would need to access the world directly. Keep functionality as local as possible, and don't make interfaces bigger than necessary.
What you can do however is put another object in Context, which acts as a bridge between the two states. An example is a dedicated small class that offers a method to query the player's position. World would then initialize that object (or a pointer to it).
-
Perhaps I could move the World member from GameState into Application, then add it to the State::Context?
What you can do however is put another object in Context, which acts as a bridge between the two states. An example is a dedicated small class that offers a method to query the player's position. World would then initialize that object (or a pointer to it).
Thanks for the suggestion. I later realized that what I'm trying to achieve almost fits an Observer or Mediator pattern:
http://sourcemaking.com/design_patterns/mediator (http://sourcemaking.com/design_patterns/mediator): ...Mediator defines an object that controls how a set of objects interact..
The "small object" you suggest could be the Mediator between State objects.
http://sourcemaking.com/design_patterns/observer (http://sourcemaking.com/design_patterns/observer): Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
Alternatively, the State class could inherit from an Observer interface, allowing State objects to publish and subscribe to whatever changes a state decides to publish.
In any case, you've pointed me in the right direction.
Thanks
-
One question to your approach of a "debug state": How can you calculate the correct fps when it is done via a state in the state stack? The state stack is updated with a fixed time step and therefore you cannot count the number of rendered frames? I wonder how the Application::updateStatistics - Member could be refactored into a member function of a debug state for that purpose?
-
I am getting the following error message when I try to compile the tutorial code.
[ 1%] Linking CXX executable 01_Intro.exe
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x11f): undefined reference to `FT_Set_Pixel_Sizes'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x2ce): undefined reference to `FT_Set_Pixel_Sizes'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x31a): undefined reference to `FT_MulFix'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x4ae): undefined reference to `FT_Set_Pixel_Sizes'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x4fa): undefined reference to `FT_MulFix'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x68a): undefined reference to `FT_Set_Pixel_Sizes'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x85a): undefined reference to `FT_Get_Char_Index'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x86b): undefined reference to `FT_Get_Char_Index'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x88a): undefined reference to `FT_Get_Kerning'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0xec6): undefined reference to `FT_Done_Face'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0xeea): undefined reference to `FT_Done_FreeType'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0xfe5): undefined reference to `FT_Init_FreeType'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1017): undefined reference to `FT_New_Memory_Face'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x102e): undefined reference to `FT_Select_Charmap'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1123): undefined reference to `FT_Done_Face'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1144): undefined reference to `FT_Done_FreeType'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x11d4): undefined reference to `FT_Done_Face'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x12d2): undefined reference to `FT_Init_FreeType'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x12fc): undefined reference to `FT_New_Face'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1313): undefined reference to `FT_Select_Charmap'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1463): undefined reference to `FT_Done_Face'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1484): undefined reference to `FT_Done_FreeType'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1543): undefined reference to `FT_Done_Face'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1646): undefined reference to `FT_Init_FreeType'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1714): undefined reference to `FT_Open_Face'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x172f): undefined reference to `FT_Select_Charmap'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1894): undefined reference to `FT_Done_Face'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x18b5): undefined reference to `FT_Done_FreeType'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1964): undefined reference to `FT_Done_Face'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1ac7): undefined reference to `FT_Done_Face'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1ae8): undefined reference to `FT_Done_FreeType'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1e98): undefined reference to `FT_Set_Pixel_Sizes'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1ec8): undefined reference to `FT_Load_Char'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1ee7): undefined reference to `FT_Get_Glyph'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1f2f): undefined reference to `FT_Glyph_To_Bitmap'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1f8d): undefined reference to `FT_Done_Glyph'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x1f92): undefined reference to `glFlush@0'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x20fb): undefined reference to `FT_Bitmap_Embolden'
C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj):Font.cpp:(.text+0x2134): undefined reference to `FT_Outline_Embolden'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: C:/SFML-2.3.2/lib/libsfml-graphics-s.a(Font.cpp.obj): bad reloc address 0x17 in section `.text.unlikely'
collect2.exe: error: ld returned 1 exit status
01_Intro\Source\CMakeFiles\01_Intro.dir\build.make:128: recipe for target '01_Intro/Source/01_Intro.exe' failed
mingw32-make[2]: *** [01_Intro/Source/01_Intro.exe] Error 1
CMakeFiles\Makefile2:84: recipe for target '01_Intro/Source/CMakeFiles/01_Intro.dir/all' failed
mingw32-make[1]: *** [01_Intro/Source/CMakeFiles/01_Intro.dir/all] Error 2
Makefile:126: recipe for target 'all' failed
mingw32-make: *** [all] Error 2
Any help? I am u sing the most recent version of SFML.
-
If you link SFML statically, you need to link against all of SFML's dependenceis, as stated in the official tutorial (http://www.sfml-dev.org/tutorials/2.3/start-cb.php#creating-and-configuring-a-sfml-project).
-
Thanks. I'll do dynamic for now since that seems easier. Don't have to modify the cmake file.
-
Hello, i have one little question:
Does this book work with SFML 2.3.2 too or do I need to use SFML 2.0?
I made bad experiences with Tutorial Books which were using older versions (some functions were out-of-date etc.).
Greetings
Ofen
PS: Sorry for writing mistakes, my english writing skills are not that good.
-
All SFML 2.x versions are backward compatible, so you can safely use the newest version. No breaking change is made: if stuff needs to be removed then it is marked as deprecated and kept until the next major version (SFML 3).
-
No breaking change is made
This is true for the code, but not for the linking, which has changed in SFML 2.2.
I recently adapted the CMake scripts (https://github.com/SFML/SFML-Game-Development-Book/commit/0eee1af4885cdcff87b15c534f3f118ae355b689) and introduced a case differentiation, so it should now work for all SFML 2 versions. If it doesn't, please report it, so we can fix potential bugs.
OfenPower, just make sure you use the code from the official repository (https://github.com/SFML/SFML-Game-Development-Book), not Packt's website.
-
If I’m not mistaken, the class Button is the only class whose instances are actually packed into containers of class Container, which holds Components together. If you had to pack a set of Components other than Buttons (say Text boxes eg.) in another Container instance, how would you proceed? The problem is that this other class would need specific methods to work with (like reading input text), not needed by nor working with Buttons.
One solution would be to create sub-classes of Container, one for each type of widget, but it feels like adding way too many classes. Any other solution?
-
If you had to pack a set of Components other than Buttons (say Text boxes eg.) in another Container instance, how would you proceed?
Use Container::pack(), that's what it's for. I don't see a problem with more classes deriving from Component (not Container), if they represent different UI components.
This is the typical Composite Pattern, by the way.
-
I don’t know if it’s a problem, but having classes like ButtonContainer and TextBoxContainer (and more) aside classes Button and TextBox (and more) seems like defeating the purpose of the original idea of a generic class Container. After all, the only need is to pack widgets of a same type and same functional group together, no more no less (and getting rid of lots of range-based for loops).
But it looks like I found my way with… lambdas. The lambda is given pointers to various widgets, and is stored inside one widget through std::function (like I had been doing so far with buttons executing code when clicked), before packing said widget into a container… a generic container. Now I don’t need to read some variable deep inside the component hierarchy and therefore I don’t need specific methods fulfilling this need; instead the std::function is executed when a certain event reaches and activates the widget.
Lambdas appear to be the foundation of my technical design, they blossom everywhere. :D
-
I'm not a fan of the license chosen for the source code. It's just going to intimidate people from using any example code for their game no matter how different it is.
If I want to use any example class from the code in a commercial project I'm technically not allowed. Technically this book is teaching me to create things I'm not even allowed to sell. This is disappointing to me as I've worked on a project very different game logic wise to the book (while still using lots of code from the book) for months and I've only just now learned of the license.
Please consider changing the license.
-
I think you understand the limitation in a wrong way. Of course you can use the concepts and ideas and let yourself inspire by our code; after all, we want to teach you something you can use in your own projects. What the license inhibits is copying our code, i.e. marketing our game. In most cases it won't restrict your freedom at all.
To clarify: It is no problem if you use features like the command system in your game, we do not own the patent on these ideas :)