I'm making a 2D game in java using the MVC pattern and after reading and searching my ass off I still haven't found a satisfying answear to how I'm supposed to handle the graphical representation of objects.
Should I divide every object, for example Player into PlayerModel (stored in Model) and PlayerView (stored in View)?
That seems kinda messy becuase then I would have to keep track of which grapical-representation-object, i.e. "ScaryMonsterEnemyView" is connected to which logical-representation-object, "ScaryMonsterEnemyModel". Is this really how I'm supposed to do it according to MVC? If so, where should this connection be stored? In the view?
I know this might be a silly problem to get stuck on, but I want to get as much as possible right from the start. Thanks for helping out :)
If I am not mistaken, you are basically asking how to split up a game into the Model-View-Controller paradigm.
Simply put, the Model is the state of your game. In O-O terms, you can think of the Model as all of the objects in your game.
The Controller is the set of rules that are applied to your game's state (in this case, all of your game objects) in every update cycle. This can be implemented as a method called update() in all of your objects, or it can be a function called in your game loop that systematically goes through all the objects that need updated and, well, updates them. You can also think of the Controller as the game loop itself. It calls everything to update, and then draws it on the screen and repeats, unless some conditions are met, then it tells the program to do something else. In this way, you almost have two nested MVC structures. One controlling the flow of the program through menus and such, and one dedicated to the game itself.
The View is just the graphical representation of your game. This can be as simple as text on a screen, but in your case it is 2D graphics. To implement this, you could have each object also contain their graphical state, either directly, or by encapsulation. The View would do little more than query all of the objects for their graphical state, and then shunt it to the screen. Again, this can be implemented on a per-object basis, such as a method called draw(), or another systematic function to be called directly from the game loop. A common practice is to create an object called 'Sptite' or something similar to hold the graphical information, and have every game object that is drawn have a personal instance. Also note that the View need not be an object unto itself. A mere function called in a game loop will suffice, although it is sometimes necessary to store information that directly effects the View's operation (like window size), in which case the View can be an object. The same goes for the Controller.
Also keep in mind that these divisions can be sectioned up even further to make life simpler. For example: The Controller can be divided up into AI processing, movements updating, and collision checking. The View could be separated into the game object display and the HUD, and the Model can be all the objects + all the state independent of the game objects (like the games settings for resolution, window size, key config and such).
I know this might be a little overkill, and it probably has extra information, but hopefully it answers your question and gives you ideas on where to start.
The Model and View are two collections/categories/domains of objects.
The controller provides a set of interfaces to perform some functions on the model objects. And if required, the view can talk directly to model objects regarding their state information.
Traditionally, The View domain corresponds to GUIs, with concepts such as Buttons, Forms, Windows etc. In a desktop environment.
Your View domain (Or one of them) will correspond to a 3D environment that you will build. (Trees, Houses, Person etc). This includes collision details, and your physics. Both of which require the geometry relating to your 3D environment.
It may be very rare in a game for any of these objects to have to collaborate with an object in another domain. But an example, consider a telephone. The object will exist in your 3D environment, but will also collaborate with another domain which describes "half-calls", "channels", "switches" etc. These objects do not belong in your View domain but in a separate Model domain.
A more relevant example maybe some sort of scoring system, such as RPG stats, which would belong in a Model domain.
Related
So I've been making board game Funny Bunny (children's game) on Java. I first made it text based but now I've been building a GUI for it using Swing. The trouble is, I've never made a GUI before and tough the GUI itself has been fairly easy to make, I find it incredibly hard to combine my game and the GUI.
I'll first explain the basic idea of the game.
THE GAME
There are 2-4 players and they all have four game pieces.
There's a deck of special card that "run" the game (4 types: move 1, 2 or 3 steps and card for changing the board.
One turn consists of player revealing a card
If it's a move card, the move a piece
If it's change the board card, the board changes and holes may open. (Some places on the board aren't safe, game pieces might drop in a hole)
So, the idea behind the game is fairly simple.
The trouble, I've got no idea how to actually make it work with a GUI. I tought it'd be rather and started enthuastically building my GUI. I made the game view (I'll add a picture), main menu, number of players menu and all that stuff just to realize that I don't know how to really make it work with event-driven game.
Game view, work in progress, never mind the colors
I'd like to GUI version work along these lines
1. First, bunch of menus for setting up the players and stuff. That's okay.
2. In the game view, player reveals a card by pushing "Show card"
3. Based on the type of the card enter either stage:
3.1 Move a game piece. This would happen by clicking a game piece (either button on the side or a piece on the game board) --> This would start move a piece process --> Requires updating the board in the end
OR
3.2 Change the board, which would updating the GUI board. I'm really lost with how to do this.
Should I use something like threads, or Swing Worker or what should I do?
Do you people want to see some sample code? That'd probably help. Just let me know, and I'll post some (it requires some translating with the comments and stuff and that's why I didn't want just randomly post parts of my code here)
All help, comments, feedback... everything would highly appreciated and really helpful. Did I already mention I'm lost and stuck? I really am.
You'll want to foster the concept of Model-View-Controller. The idea is to separate you program into layers of responsibility.
Model
The model is responsible for maintaining the data and stateful information about the program.
The model provides event notifications about changes to its state, which interested parties might need to know
View
Is responsible for representing the current state of the model(s) on the screen. It is also has direct connection to the user and is responsible for collecting user input which is handed to the...
Controller
Is responsible for binding them together. The controller takes input from the view and makes modifications to the model, based on it's rules.
The controller may even control information flowing from the model to the view.
In some implements of the MVC, the view and the model have no connection what so ever and only communicate via the controller. This is both good and bad. It's kind of bad as the controller needs to double up the communications coming from the model and pass them to the view, acting as a proxy, which can duplicate code. It's good as it protects the view and model from modifications which the controller may not allow for, based on it's rules. I tend to try and follow this model, but Swing itself hides the controller within the view, so it can seem more coupled.
This concept also relates to the idea of code to interface and not implementation. This means that the model, view and controller only know about the "contract" and not the details.
This allows you the flexibility to change the implementation (let's say, add network play-ability for example) without the need to change the entire program structure, as the components are only communicating with each other through the defined interfaces.
The overall intention here is to separate responsibility and allow each layer deal with it's own set of problems without mixing the through out the code. It also means that you can change certain layers over time with out adversely affecting the rest of the program, as they are not tightly coupled together
Now that you're probably completely confused, you could have a look at this example which demonstrates a login MVC
Not a while ago, I've made myself a card game in java.
Not gonna give specific code details cause that would be impossible here but the best advice i could give you is this.
Find a tutorial about swing. This will help you understand the basics of gui-making as well as the basic components available.
Also search about Listeners in order to make your gui work based on the logic of your game.
These things alone would be enough to create something basic (or even advanced).
Good luck with your project
This is a basic question, but since I haven't been coding Java for long I'd like to get an opinion from someone with more experience. Let's say I have a game in Java in which there are many objects (on the order of 30) on the screen. The player can click on an object and each object handles a mouse click differently.
My question is: if the player clicks on the game window, what's a good way to test if he clicked one of the objects, and if so, trigger that object's mouse click event handler?
Here's what I've come up with so far: my applet has a mouse listener and it could also have a list of all game objects currently in existence. The applet's event handler could traverse the list of objects and see if the coordinates of the click are inside that object's bounding box through something like gameObject.isInsideBBox(int mouseX, int mouseY).
This would be simple to set up, but I feel like it would be inefficient. If the number of objects is large then the program would have to traverse the list every time a user clicks. Couldn't this become a performance issue?
One alternative would be to have each object have its own MouseListener and add all the objects to some sort of global container. Would this method be more efficient in terms of performance than the above? One other concern is that these Component and Container objects seem to be defined in Java's Swing library, but I'm not using Swing for any other purposes. I have the feeling that would be a misuse of the library.
Any feedback/comments?
(I'd be interested to know if these methods would port over to Android. I realize that's a different topic, but if you have any insight on that, I'd appreciate if you could let me know.)
30 objects on screen is few enough that it shouldn't really matter much. A simple linear search should still be easily fast enough. The only real reason to consider optimizing this would be if the '30' might be way off, and you're really dealing with (say) 1000+ objects.
In that case, one simple possibility would be to sort objects by one dimension so you can do a binary search on that dimension. That should leave only a few objects to search among to find the correct value in the other direction.
As #Jerry Coffin says for a small number of objects, a linear search should be fine.
For large numbers of objects linear search scales badly.
If the objects are stationary, you can divide the screen up into a hierarchy of regions; e.g. a quadtree, and place each object into a leaf region. This allows you to reduce the number of objects you need to check.
If the objects are moving rapidly, I don't think that quadtrees would work. Every time you moved an object you'd need to recalculate its position in the quad tree, and that is expensive.
For slowly moving objects, quadtrees might work, provided that each object knows what quadtree region it is currently inside. (Check that an object is still in a region is O(1).)
each object handles a mouse click differently.
each object have its own MouseListener
Given the requirement it sounds like a good solution.
If your game objects derive from a class that implements the Shape interface, one of the conatains() methods may be sufficient. This example can handle thousands of objects using a linear search.
As a project over summer while I have some downtime from Uni I am going to build a monopoly game. This question is more about the general idea of the problem however, rather than the specific task I'm trying to carry out.
I decided to build this with a bottom up approach, creating just movement around a forty space board and then moving on to interaction with spaces. I realised that I was quite unsure of the best way of proceeding with this and I am torn between two design ideas:
Giving every space its own object, all sub-classes of a Space object so the interaction can be defined by the space object itself. I could do this by implementing different land() methods for each type of space.
Only giving the Properties and Utilities (as each property has unique features) objects and creating methods for dealing with the buying/renting etc in the main class of the program (or Board as I'm calling it). Spaces like go and super tax could be implemented by a small set of conditionals checking to see if player is on a special space.
Option 1 is obviously the OO (and I feel the correct) way of doing things but I'd like to only have to handle user interaction from the programs main class. In other words, I don't want the space objects to be interacting with the player.
Why? Errr. A lot of the coding I've done thus far has had this simplicity but I'm not sure if this is a pipe dream or not for larger projects. Should I really be handling user interaction in an entirely separate class?
As you can see I am quite confused about this situation. Is there some way round this? And, does anyone have any advice on practical OO design that could help in general?
EDIT: Just like to note that I feel I lost a little focus on this question. I am interested in the general methodology of combining OO and any external action(command line, networking, GUI, file management etc) really.
In the end, it is up to you. That is the beauty of OO, in that it is subject to interpretation. There are some patterns that should usually be adhered to, but in general it is your decision how to approach it.
However, you should carefully consider what each actor in the system should know about the rest of it. Should a property really know about the player, his account balance, and the other players? Probably not. A property should know what it costs, how much its rent is, etc.
On the other hand, should the main playing thread be concerned about trivial matters such as paying rent? Probably not. Its main concern should be the state of the game itself, such as dice rolling, whether each player wants to trade or buy or unmortgage/mortgage, things like that.
Think for a moment about the action of landing on a square. Once landed, the player has 3 options:
Buy the property
Ignore the property
Pay rent
Now, which actor in the system knows all the information required to complete that. We have the Game class, which isn't concerned with such tedium. We have the Property, which doesn't really care about the players. But the Player object knows all this information. It keeps a record of what each player owns, and can easily access the proper data.
So, if it were me, I would make a Player.performMove(Die d) method. It has easy access to the accounts. This also allows for the least coupling among classes.
But in the end, it's up to you. I'm sure people have created Monopoly clones in perfect OO, as well as Functional or Procedural languages too. In the end, use what you know and keep refactoring until you're happy with the end design.
I agree option #1 seems better.
As for "user interaction" - it all depends. You could leave some of your code in another class. For example,
// in main class
user.landOn(space);
if (space.containsProperties()) doSomething(); // Option #1 for some user-interaction code
// in User.java
public void landOn(Space s) {
// do some checks
s.land(this);
if (s.containsProperties()) {...} // Option #2
// something else?
}
// in GetMoneySpace.java
#Override
public void land(User u) {
u.awardCash(200);
// Option #3 - no properties so nothing here
}
This is far more OOP-y (and better, in my opinion) than something like
if (space.isCashAwardSpace()) {
user.awardCash(space.getAward());
}
if (user.something()) doSomething(); // Some user-interaction code
I am not entirely sure if I understand it correctly. You have always such choice when designing software. I would personally go for the first choice. One argument is personal experience with small games (Scrabble), which prooved to me that good design matters for smaller projects as well. The point of OOP is that you can think differently about your design and you get some design benefits. For example imagine how hard it will be to add new field, change existing one, reuse behaviour of one field in multiple fields.
Your first approach is the one I'd go for. It encapsulates the behaviour where it's needed. So, you'd have Space subclasses for Utilities, Properties, GotoJail, FreeParking - basically all the different cateogires of spaces. What groups a category is it's common behaviour.
Your properties spaces may themselves have a group object as a member, e.g. to group all the dark blue properties together.
As to interaction with the user, you pass a Board (or better a GameController) instance to each space, so it knows which Game it is part of and can influence the game. The Space can then invoke specific actions on the board, such as, moving a piece, asking the user a question etc. The main point is that there is separation - the user interaction is not happening inside each Space - but the space is allowed to request that some interaction happens, or that a piece is moved. It's up to your GameController to actually do the interaction or move pieces etc. This separation makes it easy to test, and also provide alternative implementations as the need may arise (E.g. different game rules in different editions/countries?)
Go with the first design. You'd have a Property class, and subclass the special properties, overriding the default behavior.
As far as interaction, you could have a Token class, and move an instance of that around the board. You have to give the user some options, but yes, from the responses, you should be calling methods on objects, not putting complex logic in the user events.
Sample classes:
Property
name
price
baseRent
houseCount
hotelCount
mortgaged
getCurrentRent()
RailRoad extends Property
Utility extends Property
Board
properties
User
token
playerName
currentProperty
ownedProperties
buyProperty()
payRentOnProperty()
mortgageProperty()
move()
Option 2 doesn't make much sense, or at least it's not as clear to me as option 1. With option 1 you don't need to handle user interaction inside your space object. You could have in your main class or a separate class dedicated to handle user interaction:
public void move(Player p, int spaces){
Space landingSpace = board.getLandingSpace(p,spaces);
landingSpace.land(p); //apply your logic here
}
As you can see, the Space class is responsible for checking the Player p that intends to land on that space. It applies any custom logic, checks if it has enough money, if it's something that the player owns, etc. Each subclass of Space will have its own set of rules, as you described in option 1.
Part of the point of object-oriented design is to simplify the representation of the problem within the solution space (i.e., modeling the system in the computer). In this case, consider the relationships between objects. Is there enough functionality in a Space to warrant abstracting that into a class, or does it make more sense for there to be discrete Property and Utility classes unrelated to Space because of the unique features of both? Is a Property a special kind of Space, or merely a field within Space? These are the kinds of problems you probably will need to grapple with in designing the game.
As far as interaction, it's generally bad news for a design when you have a 'god class' that does all the work and merely asks the other classes for information. There are plenty of ways to fall into this trap; one way to determine whether you are dealing with a god class is to look for a class name including Manager or System. Thus, it's probably not the best idea to have some sort of "game manager" that asks all the other objects for data, makes all the changes, and keeps track of everything. Eliminate these as much as possible.
God classes violate the concept of encapsulation, which involves more than data hiding (though that's certainly a big part of it). Good encapsulation means that related methods and data are part of a single object. For example, a Property doesn't need to make requests of its owner, so a field containing a reference to the Player could violate encapsulation. Some of these encapsulation violations aren't obvious at all, and can be hard to spot. When designing the object, try to determine the smallest amount of information about the object that needs to be shared with external objects. Trim out anything unnecessary.
You can obviously go about this in a lot of ways, but my design would be something like this (iteration could certainly prove it wrong):
Space class that contains basic data and methods that are common to all spaces (such as their position on the board, occupied or not, etc.).
Subclasses moving from most common (Property and Utility) to most unique (Go, Jail, FreeParking, and so on; probably singletons) with fields and methods related to each.
Player class to contain player information.
GameState class that is concerned with game state; whose turn it is, how many houses are left in the bank, and so on.
Good luck with the game and your continued studies.
Naturally, Google is your friend, but here's a sampling of things I would recommend reading:
ATM simulation (this idea is
also discussed in Rebecca
Wirfs-Brock's book below)
Object-Oriented Design Heuristics - Arthur Riel
How Designs Differ (PDF), Designing Object-Oriented Software - Rebecca Wirfs-Brock
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
For quite awhile I have been trying to make a simple "game" in Java that is really just an applet with a square and a grid. What I want it to do in the end is the user clicks and the square will move to where the user clicked rounded to the nearest grid square.
The problem is I am a self taught beginner and I am having a hard time figuring out how to actually structure the program, some examples:
should I have a separate class listening for mouse clicks?
When I receive a click should I send it to some other object that represents the box and let it decide what it wants to do or just call some function that makes the box move?
I really want to learn all this "when to use what" stuff for myself so any links or general advice is appreciated.
What you're really asking is how to develop a game, which is notably different from a typical Java application. However, I'll give you a few ideas to at least point you in the right direction.
Take advantage of the fact that Java is an object-oriented language. That is, objects should each have their own responsibility.
Separate your game into three key layers: the application layer, the game logic layer, and the presentation layer.
The application layer should contain all of your helpers and generic subsystems, things like random number generators, text parsers, file access modules, mesh loaders, etc.
The game logic layer should implement all of the rules of your game, and be responsible for maintaining canonical state. Basically, when you press the "W" on the keyboard to move forward, the game logic layer should receive MOVE_FORWARD_REQUEST from the UI.
The presentation layer should be responsible for two things: getting input, and rendering your world. When it gets input, like the "W" key, it should map that to an action, and send that to the game logic layer to be processed. Then, it should render the world based on whatever the game logic told it to do.
Game development is obviously an entire realm with many books dedicated to it. One of my favorites is Game Coding Complete, which does focus on C/C++, but should give you a good idea about how you ought to structure your game.
Good luck!
One main principle of good software development is the Single Responsibility Priciple. It states that a function or class should only have one responsibility.
This way your classes and objects shouldn't become too big and unmanageable.
I think one of the most important concepts to master when developing software is the concept or Orthogonality. It's not the simplest definition, but in essence it means that one component (such as reading mouse clicks) shouldn't be directly tied to an unrelated component (moving a square on the screen).
In your case, the code reading mouse clicks should be separate from the code that actually moves the box. Whether you implement this as inner/anonymous classes or not is up to you. But if you follow the Orthogonality principle, it will be easy to change at a later date should you change your mind.
One problem here is that all the rules have some leeway in them where you have to use your own best judgement.
For example, the app you are describing now seems to me so simple I'd probably do it in a single class, with perhaps a couple of nested, perhaps anonymous classes. In any event, I could make a decent case for fitting the whole thing into a single source file, claiming that multiple source files would actually increase the complexity of the whole thing.
But if your GUI had a number of different controls, perhaps each controlling different behavior, it would become time to split the functionality up so you're not ending up with a big bowl of spaghetti code.
The Java GUI libraries try to naturally separate (view+controller) from model. You are encouraged to define and display the GUI in one module (= file) but to have your data model and perhaps functionality in another. For complicated GUIs, there may also be multiple GUI implementation modules held together by code.
One way to keep things "clean" is to work in "layers" where each layer "knows" only what it needs to know. To be specific, the GUI layer needs to know about the existence of its underlying models – tables and lists and whatnot need to be connected to TableModels and ListModels, etc. It doesn't need to know about details of these models though, so it can simply refer to those models by interface.
The model layer, on the other hand, need know nothing about the GUI. The less it knows, the better, and this would theoretically enable you to exchange GUIs without needing to touch the models.
My model can also contain ActionListeners to respond to actions undertaken by e.g. pushing buttons in the GUI.
Of course, actions and changes to the model will often result in changes to the GUI. How to communicate these changes to the GUI if the model layer doesn't know about the GUI? You can use bound bean properties here. Here's a short tutorial: http://www.javalobby.org/java/forums/t19476.html . So you have the same kind of structure: Changes happen in your model, they're communicated to beans with property change support within the model, and the GUI can attach listeners to those properties to find out something changed.
Whether you perform actual, effective actions (e.g. writing files, converting data, whatever) within your model code or whether you split "processing" code off into yet another module is up to you and will again depend on how cluttered your model already is. If there's a tiny handful of fields and methods feeling lonely in there, you may decide to mash things together but the moment it starts to look messy you'll want to refactor your processing code out into its own module. Processing sounds like the kind of module that doesn't want to know about other modules either; you may end up just calling its methods from the model level.
I've described my basic style for doing GUI development. There are certainly other recommendations out there, and you will likely develop your own style based on your experience. This is just intended to give you an idea and a possible starting point.
Step 1 - find the demo applets supplied by Sun. http://java.sun.com/applets/jdk/
Step 2 - read those demo applets. At least three. Preferably all of them.
One you've read several applets, you should see a little more clearly how to organize programs. You can then ask questions with a lot more focus pointing to specific applet examples and your specific programming problem.
Yeah, I'm a beginner programmer myself. Yeah, segregating functionality across multiple classes is a good way to reduce complexity and increase cohesion of individual classes.
Increasing cohesion good because by having more complex data structure your algorithms become less complex and your code is less dependent on each other.
For instance in your case it might be a good idea to separate the classes in accordance to MVC (Model View Controler).
You have a Model which represents the way your game data is structured.
You have a Viewer which present your Model in what ever form you please.
Have a Controller which picks up changes in the Model (via Listeners) and then updates the Viewer
Now you can change your Model and add extra functionality requiring only small changes in the way the Viewer works.
There are many Patterns out there but there isn't a hard rule when to use one over the other. There are some cases in which you can use several and there are cases in which will require you to chose one design pattern over the other.
Every beginning Java programmer should start with the Sun Tutorials. They are quite good.
Another good source, especially among free sources, is Bruce Eckel's "Thinking in Java", available from http://www.mindview.net/Books/TIJ/.
But the latter is a little dated compared to the former. That is why I recommend both.
Whenever I try to write graphical programs (whether a game or really any GUI app) I always wind up with one or two god classes with way too many methods (and long methods, too), and each class having far too many responsibilities. I have graphics being done at the same time as calculations and logic, and I feel like this is a really bad way to go about organizing my code. I want to get better at organizing my code and abstracting out responsibilities to different classes. Here's an example of where I'd like to start - I want to write a Minesweeper clone, just sort of as practice and to try to improve my software engineering skills. How would I go about making this nice and object-oriented? For the sake of discussion, let's just say I'm using Java (because I probably will, either that or C#). Here's some things I would think about:
should each tile inherit from JButton or JComponent and handle drawing itself?
or should the tiles just be stored as some non-graphical MinesweeperTile object and some other class handles drawing them?
is the 8-segment display countdown timer (pre-Vista, at least) a separate class that handles drawing itself?
when the user clicks, do the tiles have mouse event listeners or does some other collision detection method loop through the tiles and check each one to see if it's been hit?
I realize that there's not just one way to write a GUI application, but what are some pretty basic things I can start doing to make my code more organized, manageable, object-oriented, and just over all write better programs?
edit: I guess I should add that I'm familiar with MVC, and I was originally going to incorporate that into my question, but I guess I didn't want to shoehorn myself into MVC if that's not necessarily what I need. I did searched for topics on MVC with GUI apps but didn't really find anything that answers my specific question.
edit2: Thanks to everyone who answered. I wish I could accept more than one answer..
Here is a simple (but effective) OO design to get you started:
First create a Game object that is pure Java/C# code. With no UI or anything else platform specific. The Game object handles a Board object and a Player object. The Board object manages a number of Tile objects (where the mines are). The Player object keeps track of "Number of turns", "Score" etc. You will also need a Timer object to keep track of the game time.
Then create a separate UI object that doesn't know anything about the Game object. It is completely stand alone and completely platform dependent. It has its own UIBoard, UITile, UITimer etc. and can be told how to change its states. The UI object is responsible for the User Interface (output to the screen/sound and input from the user).
And finally, add the top level Application object that reads input from the UI object, tells the Game what to do based on the input, is notified by the Game about state changes and then turns around and tells the UI how to update itself.
This is (by the way) an adaption of the MVP (Model, View, Presenter) pattern. And (oh by the way) the MVP pattern is really just a specialization of the Mediator pattern. And (another oh by the way) the MVP pattern is basically the MVC (Model, View, Control) pattern where the View does NOT have access to the model. Which is a big improvement IMHO.
Have fun!
use a MVC framework that handles all the hard organization work for you. there's a ton of MVC framework topics on SO.
using high quality stuff written by others will probably teach you faster - you will get further and see more patterns with less headache.
I'm not suggesting this is the only way to do it, but what I would suggest is something like the following. Other people, please feel free to comment on this and make corrections.
Each tile should inherit from something and handle drawing itself. A button seems like the best solution because it already has the button drawing functionality (pressed, unpressed, etc) built in.
Each tile should also be aware of its neighbors. You would have eight pointers to each of its eight neighbors, setting them to null of course if there is no neighbor. When it goes to draw, it would query each neighbor's IsMine() function and display the count.
If none of its neighbors are a mine, it would then recurse into each neighbor's Reveal() method.
For the 7-segment display, each digit is its own class that handles drawing. Then I would make a CountdownSegmentDigit class that inherits from this class, but has additional functionality, namely CountDown(), Set(), and Reset() methods, as well as a HitZero event. Then the display timer itself is a collection of these digits, wired up to propagate zeroes left. Then have a Timer within the timer class which ticks every second and counts down the rightmost digit.
When the user clicks, see above. The tile itself will handle the mouse click (it is a button after all) and call its Reveal() method. If it is a mine, it will fire the MineExploded event, which your main form will be listening to.
For me, when I think of how to encapsulate objects, it helps to imagine it as a manufacturing process for physical parts. Ask yourself, "How can I design this system so it can be most efficiently built and reused?" Think about future reuse possibilities too. Remember the assembly process takes small pieces and builds them up into larger and larger pieces until the entire object is built. Each bit should be as independent as possible and handle its own logic, but be able to talk to the outside world when necessary.
Take the 7-segment display bit, you could have another use for it later that does not count down. Say you want a speedometer in a car or something. You will already have the digits that you can wire up together. (Think hardware: stock 7-segment displays that do nothing but light up. Then you attach a controller to them and they get functionality.)
In fact if you think hard enough, you might find you want CountUp() functionality too. And an event argument in HitZero to tell whether it was by counting up or down. But you can wait until later to add this functionality when you need it. This is where inheritance shines: inherit for your CountDownDigit and make a CountUpOrDownDigit.
Thinking about how I might design it in hardware, you might want to design each digit so it knows about its neighbors and count them up or down when appropriate. Have them remember a max value (remember, 60 seconds to a minute, not 100) so when they roll over 0, they reset appropriately. There's a world of possibilites.
The central concern of a Graphic User Interface is handling events. The user does X and you need to response or not respond to it. The games have the added complexity in that it needs to change state in real time. In a lot of cases it does this by transforming the current state into a new state and telling the UI to display the results. It does this in a very short amount of time.
You start off with a model. A collection of classes that represents the data the user wants to manipulate. This could represent the accounts of a business or vast frontiers of an unknown world.
The UI starts with defining a series of forms or screens. The idea is that is for each form or screen you create a interface that defines how the UI Controller will interact with it. In general there is one UI Controller classes for each form or screen.
The form passes the event to the UI Controller. The UI Controller then decides which command to execute. This is best done through the Command design pattern where each command is it own class.
The Command then is executed and manipulate the model. The Command then tells the UI Controller that a screen or a portion of a screen needs to be redraw. The UI Control then looks at the data in the model and uses the Screen Interface to redraw the screen.
By putting all the forms and screen behind a interface you can rip out what you have and put something different in. This includes even not having any forms at all but rather mock objects. This is good for automated testing. As long as something implements the Screen Interface properly the rest of the software will be happy.
Finally a game that has to operate in real time will have a loop (or loops) running that will be continually transforming the state of the game. It will use the UI Controller to redraw what it updated. Commands will insert or change information in the model. The next time the loop comes around the new information will be used. For example altering a vector of a object traveling through the air.
I don't like the MVC architecture as I feel it doesn't handle the issues of GUIs well. I prefer the use of a Supervising Controller which you can read about here. The reason for this is that I believe automated tests are one of the most important tools you have. The more you can automate the better off you are. The supervising presenter pattern makes the forms a thin shell so there is very little that can't be tested automatically.
Sorry to say it, but it seems you have mess in your head trying to improve your coding too much in one step.
There is no way to answer your question as such, but here we go.
First start with OOP, think about what objects are required for your game/GUI and start implementing them a little at a time, see if there are chances to break up these objects further, or perhaps reunite some objects that make no sense on their own, then try to figure out if you have repeated functionality among your objects, if you do, figure out if this repeated functionality is a (or many) base class or not.
Now this will take you a few days, or weeks to really grok it well, then worry about dividing your logic and rendering.
I have some tutorials that are written in C#. It discusses this very same topic. It is a starting point for a RogueLike game.
Object Oriented Design in C# Converting Legacy Game
Object Oriented Design: Domain Type Objects
Object Oriented Design: Rethinking Design Issues
BROKEN LINK - Object Oriented Design: Baby Steps in Acceptance Testing