Advertisement Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

266 Neutral

About zdlr

  • Rank
  1. @Matias Goldberg.   About the `static const unsigned int absPlaneMask[4]`. Could you explain how that stops it being reentrant? It is read-only and never modified.    Also, re-entrancy is not sufficient to make something thread-safe. It is possible to be re-entrant and yet not thread safe, and vice-versa.
  2. @hellraizer, thanks for replying. Re references, mean this:   const _Vector3f& aabbCenter = aabbList[iAABB].m_Center; const _Vector3f& aabbSize = aabbList[iAABB].m_Extent;   Which creates constant references to the current AABB's center and extent vectors. References are a C++ construct, not C.
  3. If you're using references, is it still a 'C implementation'?   Could you please choose better variable names than 'd' and 'r'? You then exacerbate the lack of clarity by aliasing d + r to 'd_p_r' and d - r to 'd_m_r' - not forgetting the 'd' field on the _Plane struct.   Would distanceFromCenterToPlaneNormal and distanceFromSizeToAbsolutePlaneNormal not be more explicative? Example code like this benefits hugely from such verbosity.
  4. zdlr

    Critique my code please

    mepis, I've sumitted a couple of pull requests that address one or two of the points I mentioned above.
  5. zdlr

    Critique my code please

    Every time you add a new item, you have to change the GameWindow.paint method. You have a lot of hardcoded magic numbers. Like 16666666..., (userInput == 38), (userInput == 40), etc. Some objects are not encapsulated very well. Ball is just a bag of data which doesn't do anything, just holds values. It also holds values not specific to ball, like window measurements. What is the purpose of GameLoopTimer? It looks like it could be used to make movement framerate independent, but it is not used for that. Is the frequency of GameWindow.paint calls fixed in Java, or does it vary with the speed of the machine? What is the purpose of the isHard boolean? GameWindow has too many responsibilities - drawing, input detection and response, general initialization, object creation, object movement. It should delegate a lot more to other classes. 
  6. Ahhh, to me - that's a criticism sandwich! Still, tasty. Really appreciate that response, uglybdavis. I will read and digest that post. It seemed like a smell to have to implement those interfaces, so I'm glad my intuition was correct.
  7. The reason for not targeting DX11 is that interoping DX11 with D2D looks like a bit of a nightmare. There was a couple hoops to jump through with 10.1, and I understand it is even worse with 11. However, I guess that once the initialization is done, I don't really need to think about it again. Is the next-frame position of an object just assuming that the frame delta is going to be exactly the same as the current frame? That sounds... imprecise? I have split up my entities into components - the Player is composed of a Paddle (as well as a score and other such stuff) and the Paddle is IColllidable and IDrawable. The IDrawable delegates to a RectangleDrawable, which basically adapts my Math::Rectangle to also implement IDrawable. I don't have too much problem with how they are separated, I just wonder if I've perhaps gone an indirection too far? Maybe RectangleDrawable doesn't need to be given an IRenderer to which it `describes` itself. Perhaps, instead, I could just pass in to the RectangleDrawable an ID2DRenderTarget. My obvious grip with this being that, while my game entities are unaware of DX, their components are now wedded to it. Might prevent me having to effective facade DX, though...
  8. I am returning to a bit of game development after about five years away. Back then, I was lucky enough to get a job without having a portfolio of samples. However, I always started something and never really saw it through. Now that I am an experienced developer (albeit, with the bulk of my career spent in C#) I decided I would try to complete something fairly simple. The first thing I am creating is Pong, probably the simplest thing that I could think of. I am using C++ and DirectX and trying to write much of it myself - while I am relying heavily on STL and Boost, I'm not using middleware for physics, etc. Enough setup- the question I have is around organizing two types of entities: drawable entities and collidable entities. I have a renderer interface: IRenderer and then an implementation called DXRenderer which is for DirectX 10.1. This isn't for runtime late binding purposes (the projects in which they reside are static libs, not dlls) but for separation of concerns purposes. My Game class (from which I have a Pong subclass) accepts an IRenderer* and registers with it IDrawable*s. Per frame, IRenderer iterates through all of its IDrawables and - if they are not hidden - the renderer calls IDrawable::Draw(IRenderer* pRenderer), passing itself it. Now, this achieves a fairly pleasant separation of concerns, but I'm now a bit worried about the amount of work I've just created for myself. So far, I have only two IDrawable implementations: StringDrawable and RectangleDrawable. IRenderer thus has two methods corresponding to these: IRenderer::DrawFIlledRectangle(...) and IRenderer::DrawString(...). The two issues here are: having to add another method almost per IDrawable interface, and having to open up each method sufficiently to support a plethora of rendering options (so far, you can't even choose what color you want to render the rectangle or string - it's just a black brush from d2d). The second issue is pretty similar, in that it's about me painting myself into a bit of a designerly corner. The Game class has a CollisionDetector, into which games can register ICollidable objects. Per frame, the CollisionDetector iterates through all of the moving objects and checks if they have collided with something (ie: it iterates through everything else per object, this feels a wee bit heavy-handed, but is in no way slowing things down so far- still takes <1ms per frame). ICollidables only support bounding Rectangles at the moment, so one issue is how I would be able to support multiple types of bounding shape (well, for Pong I only really need rectangles and circles, but still...) The next issue is about how I go about responding to a collision. CollisionDetector retrieves the bounding rectangle of two ICollidables and finds their intersecting Rectangle, if one exists. I then pass the primary object the intersecting rectangle and a pointer to the ICollidable that it hit. If we take the example of the player's paddle moving vertically in the playing area, I have created two Wall objects: _floor and _ceiling. These are ICollidables. Currently, Paddle::Collided(...) is called and the top of intersecting rectangle is the same as the top of the Paddle, then I "know" we're in the _ceiling and need to move down the same distance as the intersecting rectangle's height. Conversely, if Paddle::Collided(...) is called and the bottom of the intersection is equal to the bottom of the Paddle, the I "know" we're in the _floor and need to move the Paddle up the same distance as the intersecting rectangle's height. Clearly, this is not going to apply to many more scenarios. Eventually, I'm going to have to pass more context into the Collided(...) method, or request it from ICollidables. Also, I'm not too happy about doing Euler integration on the velocity to get the position of the paddle, but something like RK4 is going to be massive overkill until I can justify it. I'm doing this on evenings and at weekends in between the myriad responsibilities I have, so each change I make can't really take more than an hour without seeing some tangible results. However, is this kind of 'corrective' collision detection still the norm? Ie: after the Game's Update method is called, objects have already intersected so enact some kind of restorative hack to make things look right. I far prefer the idea of predictively detecting collisions, but I guess that's also overkill for now. I do (eventually) wish to make more than just Pong with this framework, though, which is why I'm going to so many pains as to make things extensible and `neat`. Thanks, and apologies for the rambling wall of text. -Edit: Here's some code to illuminate what I'm talking about- // Update loop in my Game base class void Game::Loop(double time) { Update(time); _collisionDetector.TestForCollisions(); _pRenderer->RenderFrame(time); } // Renderer iterates through IDrawable*s and asks them to draw themselves... void IRenderer::RenderFrame(double time) { std::for_each(this->_vpDrawables.cbegin(), this->_vpDrawables.cend(), boost::bind(&DrawDrawable, _1, this, time)); } void DrawDrawable(const IDrawable* pDrawable, IRenderer* pRenderer, double time) { pDrawable->Draw(pRenderer, time); } // I need an implementation of IDrawable for everything that can be drawn. At the moment, all I can do is render black filled rectangles... void RectangleDrawable::Draw(IRenderer* pRenderer, double time) const { if(!Hidden) pRenderer->FilledRectangle(_position.Left, _position.Top, _position.Right - _position.Left, _position.Bottom - _position.Top); } //...and black strings: void StringDrawable::Draw(IRenderer* pRenderer, double time) const { if(!Hidden) pRenderer->String(_position.X, _position.Y, _text); } //To use this in a game, I need to register something as drawable: Pong::Pong(float width, float height, IRenderer* pRenderer) : Game(pRenderer), _screenExtents(width, height), _playArea(width*.05f, height*.05f, width*.95f, height*.95f), _floor(Math::Rectangle<float>(.0f, height*.95f, width, height)), _ceiling(Math::Rectangle<float>(.0f, .0f, width, height*.05f)), _playerLeft(width*.05f, height*.05f), _playerRight(width*.95f, height*.05f) { AddDrawable(&_playerLeft); AddDrawable(&_playerRight); AddCollidable(&_playerLeft); AddCollidable(&_playerRight); AddCollidable(&_floor); AddCollidable(&_ceiling); } //This does mean that Player is IDrawable, but it just delegates to its components, which will (in turn) delegate to either RectangleDrawable or StringDrawable, of which they are composed: void Player::Draw(IRenderer* pRenderer, double time) const { _paddle.Draw(pRenderer, time); _score.Draw(pRenderer, time); } Collision detection is much the same story: // I'm sure this is going to be hugely inefficient at some point: void CollisionDetector::TestForCollisions() { for(CollidableCollection::iterator i(_vpCollidables.begin()); i!=_vpCollidables.end(); ++i) { if((*i)->IsMoving()) { for(CollidableCollection::iterator j(_vpCollidables.begin()); j!=_vpCollidables.end(); ++j) { if((*i) != (*j)) // don't test for collisions between ourselves { Rectangle<float> intersection; if((*i)->GetBounds().GetIntersect((*j)->GetBounds(), intersection)) { (*i)->Collided((*j), intersection); } } } } } } // As we saw before, Player implements ICollidable, but again it delegates to components: void Player::Collided(ICollidable* pCollidable, const Math::Rectangle<float>& intersection) { _paddle.Collided(pCollidable, intersection); } // Paddle handles the collision, but this also feels like I'm doing only what will work for this specific case - I've tried to design a general solution but there is still too much knowledge that is apropos of nothing: void Paddle::Collided(ICollidable* pCollidable, const Math::Rectangle<float>& intersection) { const Rectangle<float>& position(_position.GetBounds()); if(intersection.Top == position.Top) { // we have intersected with the ceiling, move down... _position.Move(.0f, intersection.Bottom - intersection.Top); } else if (intersection.Bottom == position.Bottom) { // we have intersected with the ceiling, move up... _position.Move(.0f, intersection.Top - intersection.Bottom); } }
  9. zdlr

    Game State

    Indeed, think about the 'Pause' state, for example. For rendering, it needs to do whatever the normal in-game state does, but with a big 'PAUSED' text on the middle of the screen It still needs to poll input, but it probably doesn't need to update any game logic (moving actors, etc.) and it should only respond to the UNPAUSE command - FIRE, etc., should be disabled. So, it's a specialization of the normal game state, but by using a CompositeGameState, we can keep the concerns separate while [b]still[/b] promoting reuse. What you end up with, in essence, is a game state graph.
  10. zdlr

    Game State

    "[color=#1C2837][size=2]You are basically trading a messy class for a mess of classes."[/size][/color] [color=#1C2837][size=2] [/size][/color] [color=#1C2837][size=2]True, but each one of those classes should have very directed reason for existing - as well as being small. Far rather more classes than a big ball of mud.[/size][/color] [color=#1C2837][size=2] [/size][/color] [color=#1C2837][size=2]The Brittle Interface problem can be solved by using the Interface Segregation Principle: splitting an otherwise large interface into multiple parts, grouped logically.[/size][/color] [color=#1C2837][size=2] [/size][/color] [color=#1C2837][size=2]Furthermore, you could make a CompositeGameState and have that be the default applied to the Game. Then, the other concerns that you have inside the game (detecting the quit button was pressed, updating the keyboard and pad, plus clearing / flipping the screen) can also be factored out - possibly into a DefaultGameState or something more descriptive.[/size][/color]
  11. Great article. For future reference, it's "without further ado"...
  12. zdlr

    Question re: pointers

    Could you not return a constant reference, rather than a pointer? My C++ is a bit rusty nowadays so apologies if this is misinformed... class GameStructs { vector<GameStruct> StructList; public: const vector<GameStruct>& GetList(); } This way, you can treat the return value as a readonly value type, not a pointer, but also avoid copying all contained elements...
  13. zdlr

    becoming a Tools Programmer?

    I dabbled in tools programming while at Eidos a few years back. I'd recommend reading up on Managed C++ because you may need to interface directly with game objects which are written in C++, and you can write Managed C++ wrappers around these 'native' classes so that C# code can interact with them. Also, for the UI, Windows Forms and the Model-View-Presenter pattern is a common choice, but gaining pace is WPF and the Model-View-ViewModel pattern. Could be useful to have knowledge of those two. I never had to learn third-party scripting, but Unreal Script and Maya plugin development are often listed for tools programmer roles.
  14. zdlr

    delete problem

    0xbaadf00d 0xbaaddaad 0xdeadbeef, etc...
  15. zdlr

    Problem with Generic class in C#

    Try this? foreach (T animal in animals) { Cow cow = animal as Cow; if(cow != null) { cowFarm.animals.Add(cow); } } Also, maybe add a AddAnimal(Animal animal) method to farm and hide the animal list implementation entirely? (Or, Farm<T> could inherit from Collection<T> ?)
  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!