Комментарии:
So lets say birds are inherited from Abstract bird... And there is a method that only exist on black birds .. you made collection of abstract birds and you lost the child type .. how would you implement the dispatcher without type check and down casting
ОтветитьA simple bit test is better than a mod operation to test true or false or odd or even. Why are programmers scared of bit-manipulation?
ОтветитьHello, can someone explain why the nesting is done? I mean std::vector<std::unique_ptr<T>>.
ОтветитьHi Yan,
I have a question about the std::vector of std::unique_ptr's, because you said that the elements 'kind of had to' be heap allocated.
It really seems like they don't, because of the vector itself behaving more or less as a smart pointer.
Am I wrong?
thanks for this. you should review code that looks good on the surface but could still be improved substantially, not something like this that obviously suffers simply from too much duplication
ОтветитьThere's also a halfway way of doing this. You can put all the common stuff into a base class (or even struct) and then include an untyped pointer to the specific class for that object (along with a type marker so you know what to cast it to) in it. That way, your common code works for all game objects, and they are tightly packed in memory. When including a "dead" flag, you can even use a dumb array for game objects that are not extremely short-lived. Including a deletion counter and a garbage collection routine to pack the array when it had too many deletions also makes sense.
I like to write my own collection classes that know what kind of data they hold. This also allows me to do such trickery lie splitting the stored objects into multiple lists or filtering the objects by type (without looping over all of them because the Collection class can cheat with array slices or sub-lists by object type it keeps in sync with the main list). While the code inside that collection isn't really that different from what would be outside when using generic lists, being able to call "give_me_all_movable_and_collideable_objects_that_collide_with(player)" makes the high-level code so much clearer to read and makes it easier to change the way the data is stored easier as it's all in one place.
That thumbnail instantly reminded me of Yanderedev. On a real note, this is important because in games like GTA V which is a huge example of scope/feature creep, you want to make it modular in case if you want to add features long term.
ОтветитьWould be nice to see you rewrite code since theoretical can be very different than the actual practucal
ОтветитьThumbnail code is pretty and useful
ОтветитьThat thumbnail. Wut!? Please no.
ОтветитьLOL This could be a complete data base of the element "Bird_Types" LOL
Ответитьfirst of all this way you only need to type half as much.
private bool IsEven(int number){
if(number == 1) return false;
else if(number == 3) return false;
else if(number == 5) return false;
else if(number == 7) return false;
else if(number == 9) return false;
else if(number == 11) return false;
else if(number == 13) return false;
...
else return true;
}
I don't like the code, it could be structured way better. Functions are way too long, some more polymorpism and more modulation and the naming, like why is a vector of black birds named as black bird, like only 1 black bird!?, etc.
ОтветитьThe game objects in the program I am writing are built upon ECS.
The GameObject class is literally a wrapper for an ECS service which handles all of the component, entity and system mappings.
A lot of C/C++ programmers really have a bent toward structural programming in the likes of low level API's....
But whenever I use those APIs - I typically just wrap them back up into objects anyway.
I see why ECS is a thing.
But developers appear to latch onto certain ideas like it was their bible and guiding princple - as opposed to what it really is.
A temporary solution to a temporary problem.
For an inheritance_low implementation you could ofcourse just add an interface, not even a base class, allowing clustering them together. Delegate the hitbox to a hitbox object, reusing code isn't hard, and even if you don't like inheritance, that's not an excuse not to use composition instead
ОтветитьWut do u mean by that my code perfectly execute ;)
Ответить0 is an even number. But in C++, unlike some other languages like Python, modulo for negative numbers returns negative remainders.
ОтветитьNot rewriting the most offending sections of code really makes this less useful than it otherwise would be
Ответить"hey what's up guys my name is China welcome back to code review Series" Auto-generated captions for the win.
ОтветитьAssuming all the classes from the birds to the sparks are obstacles the player needs to avoid, it might be easier to abstract the collisions into "check if player rectangle collides with generic object rectangle," whatever is used to represent the object is just a pretty dress for a box.
ОтветитьIs Zero an even number? Is zero even a number at all? The Mathematics department back in uni had a LOT of debates about this.
Great lecture btw, ty Chernzy.
I'm very keen on seeing the impact of the refactoring considering cache-hits/-misses.
ОтветитьI'd be very interested to see a re-implementation video. I've been told by others that my code is very easy to understand - but that's because I consciously try to make it as un-sophisticated as possible. Therefore I must admit, I would have taken a similar approach to the author. I found his code very easy to read though admittedly very repetitive - so I think you were quite correct to pick up on it. 👍Also, kudos to the author for 'sticking his head above the parapet'! I know it not really like that, but you know what I mean! 👍
ОтветитьWhy does he look like MrBeast if he was 45
ОтветитьDo you do LUA? I am always looking for better ways to do things, the problem is when I want to test code outside of a game I write it for (an addon), I have to change the code to standard LUA and then back again because the game apparently uses a different code base for LUA parsing to what is latest and greatest. They also have thier own functions that dont exist in normal LUA.
ОтветитьWouldn’t doing and with one be faster
ОтветитьSecond video I've seen of you and although I'm not learning anything new in particular, I think it's nice to see someone else having similar thought processes going on when looking at this code.
As others have highlighted, it would have actually been interesting to profile this code against a refactored version of it to see whether locality rolls out the way you (and I) assume it does.
I've written similar stuff in the past using vectors holding unique_ptr without really thinking about the implications on the memory layout, but I haven't touched C++ in almost a decade to be honest, so a direct comparison for this particular case would actually be very nice.
What do you mean? It's a ladder of ifs how is a ladder not scalable 😇
fyi I'm just joking
I have written code similar to the isEven number on purpose. We had 4 or 8 hardware ports and initialy there was a for loop iterating over i ports. The benefit of having 4 or 8 explicit is that i can check split second which of them where present at specific places in code. You couldn't mess around wirh the wrong hardware accidently and we didn't had to store the iterator in memory.
But it's still good practice to keep things scalable. It's quite easy to make working code explicit once you have the necessary requirements to do so.
zero is even, come at me mathematicians
ОтветитьWe shouldn't iterate through them, we should use recursion and pure functions to allocate a completely new copy every time we change a property value. XD
Ответитьsay what you will about Cherno's methodology but "game.cpp", "gameIntro.cpp" and "gameOutro.cpp" had me in stitches for real
Ответитьhi Cherno, which software do you use to write/draw on screen while you present?
Thanks
btw, thanks for the great content in C++ series !
This code makes my head spin. There is way too much going on in each class and inside each method.
ОтветитьMaybe some demonstration with pseudocode would be useful, but I don't think a full implementation would be necessary. You're very good at explaining these things so I don't have trouble following along.
ОтветитьI spent way too long trying to over-engineer a better solution to IsEven. All it needed was constexpr and a modulo operator. lol.
ОтветитьYes to re-writing. perhaps in a dedicated series. The Code Refactor series.
ОтветитьI hate this kind of code! tidy or whatever I don't like it.....
ОтветитьI'm probably not your target audience, but I'd much rather see videos where you move quicker like "this is bullshit. Something like this would be better." And then through the magic of editing you fix it and hit the highlights of why your fix is better than the original. I'm an old dog but I'm always hoping to learn a new trick
ОтветитьCould someone explain me how to implement the component system? My little smooth procedural brain cannot comprehend how to implement components im entities and I would love to understand how it could be done
ОтветитьHonestly watching these videos and being a proponent of clean, scalable code... most of the submissions I see here are at least readable. Not perfect but at least I have an immediate idea of what's happening
Most of the legacy codebases I work with were written by complete sociopaths. Absolute shit stapled together on top of absolute shit. Impossible to read
Then again, I guess it is good to have good principles from the start so it doesnt get to that point
There would be advantage to separate lists if each list was long, and the code to be executed changed for each list. Then you'd have branching and a few cache misses between lists, but little if any branching (beyond the iteration itself) within the loop over a list. But this does still break down as the number of typed lists grows.
Ответить