Advertisement Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

308 Neutral

About de_mattT

  • Rank
  1. Agreed.   So while you'll probably still need some way of checking that the colleciton contains the key->value mapping, you only need to do it once when the key is received from the user.   Speaking in terms of a generic collection object, a return value of NULL from your function value* getThing(const key&); ) could mean that the key is mapped onto NULL or that the key is not in the map. You've already mentioned that keys will not be mapped onto null values, so in this instance a return value of NULL can only mean that the key is not in the collection. However will that always be the case? Are you intending to re-use the collection? Also someone updating the code in the future may not immediatly appreciate that a return value of NULL can only be generated when the key isn't mapped. Therefore, while NULL checks would work, I think adding explicit 'exists' checks could make your code easier to read and make the collection class more re-usable.   Both of your suggestions look like fine choices.   Another option you might want to consider, (although I'd still go with the 'bool exists(const key&)' suggestion) is to have your collection return a default object when the key isn't stored. The object would be an instance of a default class, extending the class of the values stored in the collection, but stubbing out all procedures so that they do nothing and all functions so that they return neutral values. Then the rest of your code can process the default object as if a key-value map was found, removing the need for any 'exists' or 'is NULL' checks. (The NULL Object pattern, from Robert Martin's book 'Agile Softwaree Development: Principles, Patterns and Practices')
  2. Just to add to dr01d3k4's explanation, static members are class members and therefore accessed through the class, non-static members are object (instance) members and are accessed via an object / instance.
  3. Or an alternative would be to create the instances of Appointment when you create DayPlanner, e.g. public class Planner { Appointment[] DayPlanner = new Appointment[] {new Appointment(), new Appointment(), new Appointment()}; } DayPlanner is an array with 3 elements.
  4. de_mattT


    Would this work?   class BasicComponent<T extends GroupIcon> {      List<T> icon; }   class ItemGroup : BasicComponent<ItemIcon> {      icon.Add(new ItemIcon(seed)); }   class MonsterGroup : BasicComponent<MonsterIcon> {      icon.Add(new MonsterIcon(seed)); }
  5.   This is the approach I'm currently using and it's working fine at the moment, although I cannot comment on performance as the game I'm making is pretty simple. I've created a 'ComponentCollection' class which abstracts the syncing of the two vectors away from my higher level classes. Here are some of the method/function signatures included in the public interface: /** * Associates the UID with the component. * * The component can only be added if: * * <ul> * <li> The UID has not already been added </li> * <li> If a UID with the same index is currently mapped to a component, then this * new UID will be mapped to the new component (overwriting the old mapping) only if * the salt in the new UID is greater than the salt in the currently mapped UID. </li> * </ul> * * @throws NullPointerException if gameObjectID or component are null. * * @param gameObjectID UID of game object. * @param component component to be mapped to the UID. Cannot be null. * * @return True if successfully added, false otherwise */ public boolean add(UID gameObjectID, ComponentType component); /** * Gets the component mapped to the game object UID passed in. * * @throws IllegalArgumentException if there is no component mapped to the UID (including if there is a * component mapped, but the component's UID has a different salt. * * @throws NullPointerException if gameObjectID is null. * * @param gameObjectID UID to lookup. * * @return component mapped to UID */ public ComponentType get(UID gameObjectID); /** * Removes the mapping of UID to component for the UID gameObjectID * @param gameObjectID UID for which the mapping is to be removed * * @throws NullPointerException if gameObjectID is null. * * @return True if component mapping was removed, False otherwise. */ public boolean remove(UID gameObjectID); UID is a wrapper class containing your 'CID' and 'index'.
  6. Not sure if this is exactly what you're after but here's a link to a .pdf which describes how to perform constructive solid geometry on brushes to remove coplanar surfaces.   The start of the .pdf describes thw .map file format (Quake engine games). Further in it explains how to perform CSG.   Matt
  7. Your entity_system class could store a Map of systems. The Map would use the component type as the key.   Pseudo code public class entity_system { private Map<Class<?>, base_system<?> systemMap; public void registerSystem(Class<T> componentType, base_system<T> system) { systemMap.put(componentType, system); } public <T> base_system<T> getSystem(class<T> componentType) { return systemMap.get(componentType); } }
  8.   Thinking about it my original response wasn't really about the DIP :)   If your motivation is breaking compile-time dependencies so you can compile your client code without your server code then the DIP could be applied using pure virtual classes.   However in many situations compilation dependencies won't be an issue. In these situations introducing pure virtual classes is often overkill and leads to unnecessary complexity; sticking to the idea that clients determine the interfaces of servers should produce good results.   Of course there are situations where adding a pure virtual class can improve the clarity of the design, even if the motivation is not breaking compile time dependencies.     If your motivation is breaking compile-time dependencies then I'd suggest that the decision of whether to have a pure virtual class at the top of the hierarchy depends on the volatility of BaseRenderable. If the common functionality in BaseRenderable is not volatile, merge BaseRenderable and IRenderable together.   If your motivation is not breaking compile-time dependencies, then I would suggest merging BaseRenderable and IRenderable together. There seems to be no value in having them separate.     Absolutely! This approach means that if you do manage to split Gfx3D-class in the future your client code will be unaffected.   Referring back to your original post:     When I read this it brough back memories of a really good response to a topic I read on gamedev a while back. The topic was about GUIs, but I think it's still relevant and deffinetely worth a read. Here's the link:. OO Design and Avoiding Dynamic Casts   Check out the post by dmatter about half way down the page. I believe your example is also a violation of the Liskov Substitution Principle because implementations of ITexture (and similarly for IEffect) will not be interchangable. I've never tried to create a game / engine with switchable graphics APIs, it sounds hard :). I think Iwould probably be in favor if phil_t's suggestion of compile-time switches.   Matt
  9. Single Responsibility Principle   I find SRP difficult. I do use "a class performs on the same set of data" as an indication of the number of responsibilities a class has.   You can't always look at a class in isolation and determine how many responsibilities it has, because the number of responsibilities is often dependent on how the class is used by its clients.   It's a good idea to look at the clients that are using your class and to see how much of the class each client is using, and how they are using it. This may give you an idea of the responsibilities that the clients see the class as having.   Remember also that a class can have multiple responsibilities (particularly if they are all realised using the same data members), but the responsibilities can be separated by creating a pure virtual class for each responsibility which the class inherits. Clients can then use the pure virtual class in place of the original class so that they are only aware of the parts of the class that they use.   Matt
  10. Dependency Inversion Principle   'interface' means the portion of a class that is publicly visible.  The interface does not have to be a separate pure virtual class (interface in Java / c#).   The key idea behind the Dependency Inversion Principle is that the clients impose the interface on the servers, not the other way around. The interface is owned by the clients and is designed to meet their needs.   In an attempt to adhere to this principle I started introducing pure virtual classes everywhere, but I realised that they were adding unnecessary complexity. As long as the server's interface is imposed by the client it doesn't matter if the interface is defined separately by a pure virtual class or not.   I generally treat pure virtual classes exactly as I would treat any super class. The top level class of an inheritance hierarchy should contain as much common functionality as possible (Don't Repeat Yourself). The application of the DRY principle usually dictates the type of class that will sit at the top of my inheritance hierarchies.   In saying that, sometimes a pure virtual class makes sense, as a pure virtual class describes what an object does, and not what an object is.   These principles are tools to help you manage the complexity of your design. They are a guide only and applying them effectively comes with experience.   Matt
  11. de_mattT

    Breakout collision problem?

      Is it possible you've got the comparison operators wrong? I.e.             if (ball.ballCircle.intersects(paddle.paddleRect)) {             //left (was <=, now >=)             if(ball.ballCircle.getMaxX() >= paddle.paddleRect.getMinX()){                 ball.ballCircle.setCenterX(paddle.paddleRect.getMinX()-ball.ballCircle.getRadius()-1);                 ball.setDx(-ball.getDx());             }             //Right (was >=, now <=)             if( ball.ballCircle.getMinX() <= paddle.paddleRect.getMaxX()){                 ball.ballCircle.setCenterX(paddle.paddleRect.getMaxX()+ball.ballCircle.getRadius()+1);                 ball.setDx(-ball.getDx());             }             //Top (was <=, now >=)             if(ball.balllCircle.getMaxY() >= paddle.paddleRect.getMinY()){                 ball.ballCircle.setCenterY(paddle.paddleRect.getMinY()-ball.ballCircle.getRadius()-1);                 ball.setDy(-ball.getDy());             }             }     Matt
  12. de_mattT

    Version control for begginers

    samoth makes a good point that you need to consider your needs before selecting the version control system that is right for you. It's always good to learn something new, and exposure to version control software is definitely a good thing for a future career in software development, but one option open to you is to not use any version control software. From your post it seems that you are kean to focus your attention on the development of your game, so perhpas you could simply use .zip files to create snapshots of your code at key moments (e.g. every major release). This may suit your needs just fine.
  13. de_mattT

    Rectangle Line collision problem

    Nice code example l0k0. Think I'll store a link to this for future reference. I'm not brilliant with this stuff but was wondering ifconst float bt = Dot(ptOnA - b0) / (Dot(b, b));should beconst float bt = Dot(ptOnA - b0, b) / Dot(b,b); Thanks for sharing. Matt
  • 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!