Sign in to follow this  
meteorstorm42

Question about designing with Model-View-Controller

Recommended Posts

Hi guys, I'm putting together a Tetris game, but I'm doing it mostly to practice implementing design patterns. I have a question about whether this is a "bad design practice" : Right now I have my tetrinos made up of 4 Squares, and I'm going to pass to have a function that returns these so the View / Renderer part of the program can draw them based on their positions. But... this seems sloppy somehow. It breaks information hiding / encapsulation when the Tetris piece just passes out its Squares... Do you agree? Another way I can think of doing it is to have the Squares draw themselves. But that also seems ... well, not very flexible. I'd rather the rendering part of the game is separate from the data/state part of it. I know this is probably over the top for a simple Tetris game, but I'm doing it more for design patterns and OO-design practice than anything. Any advice?

Share this post


Link to post
Share on other sites
It's not breaking information hiding if they tell the rendering system "my renderable part is made up of these four square shapes" rather than making available 'Square', the object that has game logic and so on. Does that help?

Share this post


Link to post
Share on other sites
Yeah, you can separate them better by following "programming to interface", something very basic could look like:


interface Renderable {
getVertices()
getIndices()
getMaterial()
}

class Square implements Renderable {
some data
some other data
....
getMaterial() {
....
}
....
}

class Controller {
....
render() {
view.enqueue(model.getRenderableList())
view.render()
}
....
}

Share this post


Link to post
Share on other sites
Just in case you are using 3D acceleration and wanted to render your squares as sets of indexed triangles (using 4 coordinates instead of 6 per square, not really saving much here with Tetris). You can safely ignore it, the idea is that you expose an interface from which you can get only the data needed for rendering - The renderer does not deal with game "squares", but with renderable objects, pretty much as hymerman already said.

Share this post


Link to post
Share on other sites

Alrighty, I think I get it.
I'm just using SDL, so I guess I can stick to planar coordinates for now.
(Or maybe just use 0 for the third coordinate? Might keep it more flexible for later?)
I've barely done anything with OpenGL yet, so I'm not too sure how it renders based on the vertices.
The amount I still have to learn is daunting, lol

Share this post


Link to post
Share on other sites

I ran into a snag: Implementing MVC in Java o_O

I've got the Model part down. But if I understand correctly, the Controller should handle the input, right? So far in my Java applications, I've always stuck some kind of EventListener on GUI components. That would mean that the View receives the user input... does this still work?
I can't have the View know anything about the Controller, so it can't pass the input to it... But maybe I can have it keep track of input events, and then the Controller can call a View function to retrieve them?
Or maybe I can use an Observer pattern to notify the Controller?

What do you think?
Can I create a valid MVC pattern in Java?

Share this post


Link to post
Share on other sites
Strict adherence to MVC may or may not be reasonable, but in this case I think it won't hurt. As you already surmised yourself, the Observer pattern can help you implement communication from View to Controller in a decoupled fashion. Polling would also work, if you wanted to process them all at once - depends on how you wanna handle it.

Share this post


Link to post
Share on other sites
Quote:
Original post by meteorstorm42

I've got the Model part down. But if I understand correctly, the Controller should handle the input, right? So far in my Java applications, I've always stuck some kind of EventListener on GUI components. That would mean that the View receives the user input... does this still work?
I can't have the View know anything about the Controller, so it can't pass the input to it... But maybe I can have it keep track of input events, and then the Controller can call a View function to retrieve them?
Or maybe I can use an Observer pattern to notify the Controller?


Basically, you seem to be worried about the View/Controller separation (pulling the Model apart from the other two is generally straightforward). Don't worry about it too much; in a sense, the whole "Listener" thing is already acheiving that separation.

Share this post


Link to post
Share on other sites

After some more work, I ran into another design difficulty:

If the Controller handles translating the user's input, but I have different possible game states (PlayingState, MenuState, etc.) that correspond to different Views (extended JPanels in my case), what would be the best way to handle input differently for the different States?

Right now, I have a stack of States in my Model class. It seems like the right place for it (afterall, the Model is supposed to be all about the application's state).

But for the Controller to handle input differently based on game state... do I need something similar in the Controller? (To keep track of the game state? ...sounds like the Model's job...) Do I just have the Model's State classes contain generic methods like leftArrowKeyPushed() ? (...sounds like the Controller's job) Perhaps I should move the State stack out of the Model?
None of these ideas sound great :/


This isn't my first game, but it's definitely the first time I'm trying to design one instead of hacking one together. Harder than I thought...

Any advice?

Share this post


Link to post
Share on other sites
I view states like an FSM controlling the game so they usually are owned by the main gameloop controller and contain flow logic (hence would be considered part of Controller in MVC). The state does the usual thing controllers do: update the model and render the view. States differ in the startup code (loading level/menu, etc, but this part could be externalized to xml) and which exact subsystems they create and use (right now I don't really find much use for this pattern but the coding overhead for this stuff is minimal anyway). Input flows from the hardware to the state, from where I kind of break the whole MVC pattern (or so I think) by propagating input down the UI's widget tree. Well, you could consider the UI tree to be part of the model, and then it's fine.

I think the takeaway is what Zahlman already mentioned: don't go overboard. I know I spend a lot of time agonizing over the design without writing much code. Not good. Get a half-way decent separation of concerns in place and try to reduce tight coupling but keep in mind the rule of: once, twice, refactor. Your design does not have to be perfect right off the bat.

Here is a good article about using MVC in games, which goes into separation of concerns and which part can talk to which other part and in what manner.

[Edited by - lightbringer on June 4, 2009 11:42:51 PM]

Share this post


Link to post
Share on other sites
Thanks for the advice!
Read most of the article but got distracted by coding :)
I'll finish it tomorrow.


Here's a UML diagram for Pong. (Trying to practice some UML before next semester...)
I just started coding, and I'm running into little hic-ups all over the place, and came up with tons of questions...
Anyway, here it is:

http://yfrog.com/04pongumlj

I don't like what's happening to the right side of the diagram :/
The Menu/Playing State/View thing bothers me, though I'm not sure if there's a neater way to do it.

Aside from that, I'm not too sure where AI fits into game design. (What class uses the AI?) I'm assuming it gets called at the same time the user's input is taken though.
How does the AI get the info it needs? I think I read somewhere that the AI gets it's own View? (or something similar?) Or is it a bad idea to give the AI access to the Model?

Also, where does the Physics fit into a game? It's laughably simple in Pong, but is there usually a Physics class/package/subsystem that gets called to iterate over sets of objects? Is that how it works?
(This would be the part that moves the Ball along in Pong, or detects collisions, right?)

Sorry for the newb questions guys...
I'd appreciate any advice you can give me :)

Share this post


Link to post
Share on other sites
Quote:
Original post by meteorstorm42
I don't like what's happening to the right side of the diagram :/
The Menu/Playing State/View thing bothers me, though I'm not sure if there's a neater way to do it.

Well, your entire solution is a bit over-engineered for Pong :) If you want to keep it this way, Input will be generating events in the view, which states can register for.

Quote:
Original post by meteorstorm42
Aside from that, I'm not too sure where AI fits into game design. (What class uses the AI?) I'm assuming it gets called at the same time the user's input is taken though.

Presumably, a separate controller attached to each controllable entity. You can update them all at once. For more complicated games you'll want some scheduling algorithm to span long AI calls over multiple frames.

Quote:
Original post by meteorstorm42
How does the AI get the info it needs? I think I read somewhere that the AI gets it's own View? (or something similar?) Or is it a bad idea to give the AI access to the Model?

AI gets info from the world by either polling the world state for the info it needs (isDoorNextToMeOpen()) or by responding to events (EVENT_PLAYER_SIGHTED)

Quote:
Original post by meteorstorm42
Also, where does the Physics fit into a game? It's laughably simple in Pong, but is there usually a Physics class/package/subsystem that gets called to iterate over sets of objects? Is that how it works?
(This would be the part that moves the Ball along in Pong, or detects collisions, right?)

For Pong, this would be something like Entity.update() which does (if (wantedDirection==LEFT) position.x-=1). For more complicated games you can put this stuff in a separate component and iterate over them all at once, perhaps running the simulation using ODE, Bullet, PhysX, Havok, or your own simulator - depends on what you need.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this