¿Es este un patrón de diseño? Si es así, ¿cuál es su nombre?

I'm currently developing a turn-based RPG (a rogue-like) in C++ and I have created a neat architecture in my code that looks like some design pattern because I remember having seen code structured like this in some other projects. I want to know if this is some kind of design pattern that I have stumbled upon and if so, what is its name. I have deliberately applied some patterns such as Factory and Singleton in other parts of the program, but the following is a rough description of another part of the program which I don't know if it's a pattern or not:

I have a base-class called GameElement, which is the root of every object that may appear within the game field. This class implements basic and complex behavior about moving around, detecting collisions, etc. that all subclasses inherit because it's common behaviour regardless of the type of the element. Plus, it has 2 virtual methods which by default do nothing, but can be overriden by subclasses: handleCollision( GameElement* e ) y handleTurn(). Las handleCollision method can be reimplemented so that the objects know what to do when they collide with another object (especially with the player), and the method handleTurn exists so that the objects have an opportunity to do whatever they want when it is their turn. So far I have created several subclasses, namely SolidElement, PushableElement, FighterElement (for the player and enemies), PlayerElement (the player) which inherits FighterElement y EnemyElement (the root of all evil) which also inherits FighterElement.

También hay una clase llamada Motor de juegos which encapsulates the game loop (which also has the SDL event loop) in the correr() method. This is the (fairly short) implementation of this method:

void GameEngine::run()
{
    SDL_Event evt;

    while ( running ) {
        handlePlayerCollisions();
        handleTurns();
        updateScreen();
        delay();

        SDL_PollEvent(&evt);

        if ( evt.type == SDL_KEYDOWN )
            handleKeyInput( evt.key.keysym.sym );
            continue;
    }
}

Within the game loop, it calls handlePlayerCollisions which has a loop that passes through the entire GameElement* container in the current scene, calling handleCollision( player ) in each one of them, so that if that element is colliding with the player, depending on the type of the element, it can do something to the player such as hurting, blocking his way, moving along (i.e. being pushed), or anything else that the class implemented in its handleCollision method. Also, the method handleTurns is called, which does almost the same thing as handlePlayerCollisions, except that it calls handleTurn in every element so that they can do what they like. The other method called is updateScreen, which does exactly what its name says it does. And the last thing is the SDL event loop used to handle key input.

If this architecture is some kind of design pattern, and if I knew what pattern it was, it would be much easier for me to use it in other projects and it would take much less time to explain it to other people when I need or have to.

preguntado el 29 de junio de 12 a las 20:06

Don't know if this setup has a name, other than "deep hierarchy mess". If it is a design pattern, then it is an anti pattern, as it is usually considered to be bad design. See e.g. this article for more on the problem and how to do it better: cowboyprogramming.com/2007/01/05/evolve-your-heirachy -

Harsh. I don't know that th OP was just referring to his game entity hierarchy in regards to the pattern question. Anyway, patterns are not usually whole programs or frameworks or engines. What you've got here is larger than a pattern. -

@tcarvin I actually misread this as not the own design by OP, but rather as something found from an FOSS project. Fernando, sorry for the disrespectful choice of words there. This is a design I have used in the past and it turned out to be a mess. I still have my notebook where I am pondering where the place of a in-game-backpack is in such a hierarchy. There are so many different aspects, that just can't be sensibly expressed in a class hierarchy. So really look for a component based design. That's the point of my comment. -

Components are complicated so a lot of programmers love them. Sadly, they too tend to turn into this "deep hierarchy mess" so instead of solving that problem they just make it that much worse because now you have no idea what functionality any given item has unless you iterate its components. Unfortunately, the folks who have seen the light on that topic spend more time making games than writing articles. ;) -

2 Respuestas

Not quite what you have, but the pattern for many simulators is based on the Bucle OODA - observe, orient, decide, act - or the variant Sense Decide Act . In a game or simulator with a visualisation, you tag rendering into each loop cycle.

For your game, handlePlayerCollisions() is part of the observing step - each component is determining whether it is in the same place as player. Presumably handleTurns() has decisions to follow or run away from the player, and other decisions and actions. updateScreen renders the current game state. Separating acting from observing and deciding allows simulations to compute all observations from known state, then compute decisions from known observations, then compute actions from those decisions means you do not skew the simulation so latter entities are observing the results of the actions of earlier entities in the same cycle. But since you have limited to observing only the player and lumped observe, decide and act together you don't have that guarantee (unless updateScreen also includes updating the simulations state).

Whether the entities in the games are a single deep hierarchy, aggregations of components or concerts of intelligent behaviours is another discussion.

Respondido 14 Jul 12, 11:07

The methods you describe are an implementation of "Template Method" (GoF) pattern http://www.vincehuston.org/dp/template_method.html

Respondido 14 Jul 12, 11:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.