What is the best approach to switch to different scenes/areas in a 3D game from the render area?
Say you have a character and he moves into a new area, how would you go about unloading the area and loading the new area. Would you just load the render function up with different loading calls and only load them if they fell within certain parameters or would you create enumerators for each area and use something like a switch statement to switch to the new area after unloading your data for the current area?
I have always created REALLY bad transitions on small games I have made for a hobby and it usually kills my performance at some point or time.
Using enum or/and switch/case is not very flexible.
You can simply use a function, example load_area(i), to unload a previous level/area then load level i instead (it could use a smart resource manager as suggested by
Andon M. Coleman).
You should separate the resource handling from the game logic and the engine. Example, the rendering system should display currently loaded drawable resources rather than looping through enums and select which scene to render.
You should minimize the unloading/loading phases; depending on the game, you can completely avoid discrete transitions by using an LOD-like (level of detail) manager that updates resources dynamically depending on the current state of the game.
This is entirely a best practices type question, so the language is irrelevant. I understand the basic principles of MVC, and that there are different, subtle flavors of it (i.e. views having a direct reference to models vs. a data delegate off the controller).
My question is around cross MVC communication, when those MVCs are nested. An example of this would be a drawing program (like Paint or something). The Canvas itself could be an MVC, but so could each drawn entity (e.g. Shapes, Text). From a model perspective, it makes sense for the CanvasModel to have a collection of entities, but should the CanvasView and CanvasController have corresponding collections of entity views and controllers respectively?
Also, what's the best/cleanest way to add a new drawn entity? Say the user has the CircleTool active, they click in the Canvas view and start drawing the shape. The CanvasView could fire relevant mouse down/move/up events that the CanvasController could listen to. The controller could then basically proxy those events to the CircleTool (state pattern). On mouse down, the CircleTool would want to create a new Circle. Should the Tool create a new CircleEntityController outright and call something like canvasController.addEntity(circleController)? Where should the responsibility of creating the Circle's model and view then lie?
Sorry if these questions are somewhat nebulous :)
--EDIT--
Here's a pseudo-codish example of what I'm talking about:
CircleTool {
...
onCanvasMouseDown: function(x, y) {
// should this tool/service create the new entity's model, view, and controller?
var model = new CircleModel(x, y);
var view = new CircleView(model);
var controller = new CircleController(model, view);
// should the canvasController's add method take in all 3 components
// and then add them to their respective endpoints?
this.canvasController.addEntity(model, view, controller);
}
...
}
CanvasController {
...
addEntity: function(model, view, controller) {
// this doesn't really feel right...
this.entityControllers.add(controller);
this.model.addEntityModel(model);
this.view.addEntityView(view);
}
...
}
Wow, well I have perhaps a surprising answer to this question: I have a long-standing rant about how MVC is considered this beatific symbol of perfection in programming that no one sees any issues with. A favorite interview question is 'what are some problems, or challenges that you might encounter in MVC?' It's amazing how often the question is greeted with a puzzled, queasy look.
The answer is really quite simple: MVC relies on the notion of multiple consumers having their needs met from a single shared model object. Things really start to go to hell when the various views make different demands. There was an article a few years ago where the authors advanced the notion of Hierarchical MVC. Someone else came on in the comments and told them that what they thought they were inventing already existed: a pattern called Presentation-Abstraction-Controller (PAC). Probably the only place you see this in the pattern literature is in the Buschmann book, sometimes referred to as the Gang of Five, or POSA (Pattern-Oriented Software Architecture). Interestingly, whenever I explain PAC, I use a paint program as the perfect example.
The main difference is that in PAC, the presentation elements tend to have their own models, that's the A of the PAC: for each component, you don't have to, but can have an abstraction. Per some of the other responses here, then what happens is you have a coordinating controller, in this case, that would rule over the canvas. Let's say we want to add a small view to the side of the canvas that shows the count of various shapes (e.g. Squares 3, Circles 5, etc.). That controller would register with the coordinating controller to listen on a two events: elementAdded and elementRemoved. As it received each notification, it would simply update a map it had in its own Abstraction. Imagine how absurd it would be to alter a shared model that a bunch of components are using to add support for such a thing. Furthermore, the person who did the ShapesSummary component didn't have to learn about anything, but the event protocols, and of course all its interactions with collaborators are immutable.
The hierarchical part is that there can be layers of controllers in PAC: for instance, the coordinating one at the Canvas level would not know about any of the various components with specialized behaviors. We might make a shape that can contain other things, which would need logic for accepting drags, etc. That component would have its own Abstraction and Controller, and that Controller would coordinate its activities with the CanvasController, etc. It might even become necessary at some point for it to communicate with its contained components.
Here's the POSA Book.
There are many different ways to attack this. I don't disagree with the other answers posted here.
However, one way that I've done this is by using the observer pattern. And let me explain why.
The observer pattern is necessary here because these drawing tools are nothing without the canvas. So, if you have no canvas, you can't (or shouldn't) invoke the circle tool. So instead, my canvas has a host of observers on it.
Each tool that can be used on the canvas is added as an observable event. Then, when an event is fired - like "begin draw" - the tool is sent as the context (in this case 'circle'). From there, the actions of the circle tool execute.
Another way to imagine this is that each layer has its own service, model, and view. The controller really is at the exterior level and associated with the canvas. So, services are only called by other services or by a controller. There are no circle tool controllers - so only another service (in our case the observed event) can call it. That service is responsible for aggregating the data, building the model, and supplying a view.
The RenderingService (for lack of better name - the thing that manages the interaction of shapes) would instantiate new Circle domain object and informs about it (either directly or when view is requesting new data) the view.
It seems that you are still in a habit of dumping all your application logic (interaction between storage abstractions and domain objects) in the presentation layer (in your case - the controllers).
P.S. I am assuming that you are not talking about HMVC.
If I were you I would opt for Composite pattern when working with shapes. Regardless of whether you have circles, squares, rectangles, triangles, letters, etc, I would treat everything as a shape. Some shapes can be simple shapes like lines, other shapes can be more complex composite shapes like graphs, pie charts, etc. A good idea would be to define a base class that has a reference to basic shapes and to advanced (complex) shapes. Both basic shapes and advanced shapes are the same type of object, its just that advanced shapes can have children that help define this complex object.
By following this logic, you can use the logic where each shape draws itself and each shape knows its location, and based on that you would apply certain logic and algorithm to ask which shape was clicked and each shape could respond to your event.
According to the GoF book:
Intent
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
Motivation
Graphics applications like drawing editors and schematic capture systems let users build complex diagrams out of simple components. The user can group components to form larger components. [...]
The key to composite pattern is an abstract class that represents both primitives and their containers. For the graphics system, this class is Graphics. Graphic declares operations like Draw that are specific to graphical objects. It also declares operations that all composite objects share, such as operations for accessing and managing its children.
Now, back to your problem. One of the base functions, as previously mentioned, is a Draw method. This method could be implemented as an abstract method in the base class with a following signature:
public virtual void Draw(YourDrawingCanvas canvas);
Each shape would implement it's own version of Draw. The argument that you pass them is a reference to the drawing canvas where each shape will draw itself. Each shape could store a reference of itself in its internal structure and it can be used to compare mouse click location with these coordinates to inform you which shape was clicked.
From my point of view using nested MVC components is kind of an overkill here: At each point in time the model contains multiple elements (different circles, squares etc., which may be nested constructs using the Composite pattern, as mentioned in another answer). However, the canvas that displays the elements is just a single view!
(And corresponding to the single view there would only a single controller be needed.)
One case of having several views could be a list of elements (which is shown, e.g., next to the canvas) - then you could implement the canvas and the element list as two distinct views on one and the same model.
Regarding the question of how to "best" implement adding an element: I would consider the following sequence of events:
The view notifies its listeners that a new circle element has been drawn (with the middle point and an initial radius as parameters, for example).
The controller is registered as listener to the view, so the controller's "draw-circle(point, radius)" listener method is invoked.
The controller creates a new circle instance in the model (either directly, or via a factory class which is part of the model - I think there are lots of different ways of implementing the creation of new elements). The controller is "in control" (literally), so I believe that it's the controllers responsibility to instantiate a new element (or at least trigger the instantiation).
In the model, some kind of "add element" method is invoked by the previous step.
The model raises a "new element created" notification to all of its listeners (probably passing on a reference to the newly created element).
The canvas is registered as listener to the model, so the canvas' "new element created (element)" listener method is invoked.
As response to the latter notification, the canvas draws the circle (on itself).
This is just an idea, but consider if the mediator pattern is applicable.
From the gang of four:
Intent
Define an object that encapsulates how a set of objects interact.
Mediator promotes loose coupling by keeping objects from referring to
each other explicitly, and it lets you vary their interaction
independently.
Applicability
Use the Mediator pattern when
a set of objects communicate in well-defined but complex ways. The resulting interdependencies are unstructured and difficult to
understand.
reusing an object is difficult because it refers to and communicates with many other objects.
a behavior that's distributed between several classes should be customizable without a lot of subclassing.
Consequences
The Mediator pattern has the following benefits and drawbacks:
It limits subclassing. A mediator localizes behavior that otherwise would be distributed among several objects. Changing this
behavior requires subclassing Mediator only; Colleague classes can be
reused as is.
It decouples colleagues. A mediator promotes loose coupling between colleagues. You can vary and reuse Colleague and Mediator classes independently.
It simplifies object protocols. A mediator replaces many-to-many interactions with one-to-many interactions between the mediator and
its colleagues. One-to-many relationships are easier to understand,
maintain, and extend.
It abstracts how objects cooperate. Making mediation an independent concept and encapsulating it in an object lets you focus
on how objects interact apart from their individual behavior. That can
help clarify how objects interact in a system.
It centralizes control. The Mediator pattern trades complexity of interaction for complexity in the mediator. Because a mediator
encapsulates protocols, it can become more complex than any individual
colleague. This can make the mediator itself a monolith that's hard to
maintain.
I am assuming MSPaint-like behavior, where the active tool creates a vector graphic glyph that the user can manipulate until he's satisfied. When the user is satisfied, the glyph gets written to the image, which is a raster of pixels.
When the Circle Tool gets selected, I'd have the CanvasController deselect the previously active tool's MVC trio (if another tool was active) and create a new CircleToolController, CircleModel and CircleView. The previously active glyph becomes final and draws itself to the CanvasModel.
The CanvasView will need to be passed a reference to the CircleView so it can draw the CanvasModel's pixels to the screen before the Circle gets drawn. The actual drawing of the circle to the screen, I'd delegate to the CircleView.
The CircleView will therefore need to know and observe other, more general, model classes besides the CircleModel, I'm thinking of a color selection / palette model, and a model for fill style and line thickness, etc. These other models live as long as the application does and have their own View and Controller. They are quite separate of the rest of the application after all.
As a sidenote: You could actually split off the drawing of the CanvasModel (the raster of pixel colors) by the CanvasView from the coordination of the updating of the entire screen. Have a higher level PaintView which knows the CanvasView and the active GlyphView (for example the CircleView) coordinate the drawing between the CanvasView and the GlyphView.
Im developing a game on Java, and wanted to keep my code separated in packages for the hud/gui and the game logic so that code can be reused in some other project, and where objects to be drawn call methods from another class or classes (maybe a "rendering context" like a group of classes just made for the drawing or something like that), the problem is that i can't find the best way to achieve this, because I've researched the web (also this forum) and the design patterns but despite some looked interesting (like Model-View-Controller), I couldn't find something that suits me, neither the common approach to solve this problem.
I've been told to make the objects to implement some drawable kind interface, and in another class called by this objects, some object which implements drawable and inherits from canvas, for example, so that if i would want later to change the objects drawing or displaying methods for another one better, for example from awt to swing, to be able just rewritting those classes and dont need to worry about my objects code,
any help would be greatly appreciated, thanks in advance!
What I do is typically along the lines of:
Create your game objects completely independent of all things visual. I'm going to use chess as an example. Each chess piece inherits a "GamePiece" interface and knows it's valid moves, what "color" it is (not visual color, but what "side" it's on), etc. But these pieces do not have any code related to drawing themselves. None. Basically pretend like you're playing a game inside the computer and never need to draw it. Design your whole game this way. You'd need a GameDirector that manages the various pieces, the GameBoard, and abstract Players. But still, no visual representation. There's a lot of leeway in exactly how you design your class hierarchy but leave the visuals out of it.
You communicate state changes by raising events, this is key. So when a player moves, an event is raised. When the GameDirector detects checkmate, an event is raised, etc.
Then you have a GameRender class that contains a GameDirector. It listens for these events and updates the visual scene accordingly (whether it's a simple 2D thing or complex 3D animation). This class can optionally have sub-components that are responsible for rendering sub-components of the game but that's not strictly necessary.
I am wondering if some of you are aware of the architectural approaches taken by the Wave team to build its GWT web client? Since i am trying to optimize performance of one GWT app designed for mobiles, it is hard not to admire its speedy credentials :)
Is Wave not using GWT-RPC to get regular updates from server? Firefox tracks some JSON communication going over the wire but nothing like RPC stuff.
How do they proceed when, for instance a new wavelet is sent. Is there a view object for every wave DTO, or they use some other pattern?
How is GUI updated after a response with, say, a new Wave arrives. Would the whole area with wavelets being rerendered or the use some smart techniques to ensure that only particular element is touched?
Thanks
This is probably information overload, but since Google Wave is open source you can actually look at how they set things up here.
If you look at WaveView.java, for example, you can see that they are using a client-side event bus like Ray Ryan mentioned in this talk at Google IO 2009. I seem to remember seeing another video where they talked about these aspects of Google Wave:
They use an event system to fire off events when something happens on the client side. The event system manages communication with the server, passing event information up to the server, getting events back from the server, and publishing those events that come back. The event bus uses a kind of buffer so that if a bunch of events are fired off in rapid succession, they can send them all in one batch. For example, when a new Wave arrives, an event with the wave information would get fired, and any portions of the UI that are actively listening for that event would be notified, so that they could determine whether they needed to change themselves accordingly.
They used seam points (or some such; I can't remember the name) to make it so that GWT could break the code up into modules, and only load up the portions that actually need to be used. Since the wave ui javascript file was originally over 1MB (minified and compressed), that was pretty important.
Since only certain waves and wavelets would be visible at a time, they actually used some complex techniques to reuse the same DOM elements. So as you scroll down through your list of waves, it's actually taking the DOM element representing the wave at the top of your inbox, changing the information inside, and moving it to the bottom of your scroll area, leaving a blank space in the part of the scroll area that you're not seeing anymore.
Additionally, I'm pretty sure they use something like Comet with JSONP to maintain continuous communication with the server, so they're not polling the server constantly for new updates, but rather there's a dynamically-generated javascript file that's being loaded in incrementally from the server, which contains instructions to fire whatever events the server has decided need to be fired.
I have to write a multiplayer pacman game in Java for a university assignment and I'm after some feedback for my design so far.
So I'm trying to go down an MVC style and this is what I've sketched out.
I've never designed anything using MVC, so my knowledge is really only from the pragmatic programmer and a short lecture so it's quite possible I'll have misunderstood or misinterpreted it slightly.
Also, most of the tutorials I've seen for designing simple games don't mention MVC at all so is this a case where MVC is not a good pattern to use?
My idea so far is that the Game State class would be the main source of data storage as it were, and would use a 2d array to store the state of the game, where the ghosts are, where pacman is etc.
The Game class would be the main controller class that would contain the main game loop and control all the interactions between the data (game state) and the view (probably a GUI representation - I just added text based really as an example).
After I've got the game working I'm going to have to split it out into client/server. It seems to me, by using this model, that it wouldn't be too hard to keep most of the the data and processing on the server and have the clients interact with the controller and draw their own views. I have no idea (yet) how this may effect the performance of the game over a network so I'll have to research into that further once the single player version is done.
Any tips or advice, based on my design so far, would be greatly appreciated - also bearing in mind that it will eventually have to be a multiplayer game.
Cheers,
Adam
On the contrary: MVC is actually a very good thing to use for this type of problem and the Swing framework does a really nice job at supporting it.
You should probably first read up on MVC. Just as an overview, you will be trying to separate how the game is represented internally (the model), from how it is drawn (the view) and how that state is to change (the controller).
First think about everything you need to model the current state of the game. Having an Entity that defines some basic behavior and subclassing it for the PacMan and Ghost like you do is probably a good way to start, but you'll probably want to call your Map a GameBoard or the like (giving things the same name as library classes is generally a bad idea: you don't want to confuse it with java.util.Map). To wrap up the model section, you probably want to wrap them all up in one class who 'knows' the entire state of your game. Since this is your GameState class, you probably want to redraw your arrows.
Since determining the view is likely to be fairly easy, you can go there. You can give your GameState a draw(Graphics) method and invoke this from whatever your view is (which you'll decide later). This might in turn delegate do each of your Entities, who might in turn delegate it to a Sprite or Image object that they have. Now your view, who's likely to be a JPanel or the like, can just call draw() using its own Graphics object from within its paintComponent() method.
Now you still need a controller to actually make stuff happen. This is likely to be some object with a KeyListener hooked into the view as well as an InputStream and an OutputStream to handle communication with the other player (it probably also needs to be the one to worry about synchronizing the game state). It also needs to also have a timer so that it can tell the units to update periodically. You do need to decide who makes the decisions on whether the moves are legal: the controller could do it, the GameState could, or it could just give the Entities the information they need and let them do it themselves.
Once you have all of these parts, you can wrap them up in one final class who knows everything and gets it all set up and such. There's a lot more that I'm glossing over and several more decisions that you have to make, but it should get you going.
I agree with James entirely, and would like to add that you might also want to make sure that this 2d array of yours for the game state can handle some edge cases like multiple ghosts occupying a tile, a pacman and ghost in the same tile (depending on how you handle it in your code), the pacman's food dots, etc.
Good planning more often than not makes the best programs, I'm glad to see you have started off with a diagram.