Click here to Skip to main content
15,867,330 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hi,

A question related to neat OO design of a WinForms game.

I have Game.cs and from this file I make a new instance of Board.cs (for showing the game; i.e. "Form1"). When doing the new instance I also send an array of gamepieces. On the Board, the gamepieces get represented by draggable imageboxes. Basically, the form works like a TV set, just showing what I have in my Game class.

So far so good. Now my question is: If I drag a picturebox (or do something else for that matter), how do I pass this info back to Game.cs? In a simpler game I would just pass variables back and forth using return;, but in this case nothing would happen until I move something and relase it (MouseUp event) or similar; i.e. Board.cs listens for all kinds of input from the user. Using a return statement sounds clumpsy to me.

Similarily, I wonder what the best idea is for actually creating an instance of Games in Program.cs, as yields an error:

static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Game());
        }

Error	1	The best overloaded method match for 'System.Windows.Forms.Application.Run(System.Windows.Forms.ApplicationContext)' has some invalid arguments

Error	2	Argument 1: cannot convert from 'WindowsFormsApplication1.Game' to 'System.Windows.Forms.ApplicationContext'



I am also a bit confused as I found this reply on a similar question: "Lastly, I've ALWAYS hated it when when a Form extends something other than a Form. This makes it very fragile." In other words, it seems as that person wouldn't use a class (other than the Board.cs form) for the "heart" of the game.

I'd really appreciate an answer as it's hard to search for this on Google.

Thanks!
Posted
Updated 21-Nov-14 14:25pm
v2
Comments
BillWoodruff 21-Nov-14 20:31pm    
Let's say I click-and-drag on PicturBox7 that represents GamePiece7: what information do you want sent to 'Game.cs: the address of every point its top-left corner moves to as it is dragged, an off-set representing deltas from its starting point ... or ?

Are there any constraints on the movement of a piece, or where the piece "ends up" as, for example, with moving a knight in a chess game ?

The PictureBoxes you use to represent pieces are created at run-time by the code in Game.cs ? Or, you have a bunch of them created in advance when your application initializes Board.cs, and you just make them visible ?

What types of data-structures in Game.cs do you use to store the information for each piece in ? I assume from your description that you don't want these structures exposed directly to the Board object: is that correct ?

A little more detail, please.
BillWoodruff 21-Nov-14 20:38pm    
Just saw your recent edit: I assume you left out [STAThread]; if Game.cs is not a WinForm, then, no, your WinForm app cannot use it as an argument to Application.Run, but that's easy to work-around.

There's absolutely nothing wrong with having a class (Game.cs) that starts, and controls, a WinForms app; in fact that architectural choice is a step towards Model-View-Controller structure, which can be a very good thing.

If you respond to the questions in my first comment, I'll post some ideas.
petter2012 22-Nov-14 20:13pm    
Hi,

Thanks for your replies! Here are the answers to your questions:

Yes, for this particular game at least, think chess/checkers etc.

Game.cs cretes an array of Pieces from a PieceCollection.cs class. This array is sent to Board.cs. In Board.cs, I dynamically create pictureboxes representing the pieces (and empty sqaures too), so that each position in the array is, via a normal nested for loop, put at a new Point(100*i, 100*j). In other words, a pawn at PieceArray[1,4] is drawn as a 100*100px picturebox at x=100 and y=400.

I also add drag'n'drop behaviour to the picturebox on the fly.

So the question is: How do I get the mouseup behaviors (meaning that a piece has been moved) to be reported back to Game.cs? I can calculate so that the move is rounded correctly, so the only thing I need to send back is integers for the new position in the PieceArray. Of course, some (most) moves are illegal, and when the move has somehow been reported back to Game.cs, Rules.cs is called to check if the move is okay or not. If not, the original array is sent back to Board.cs to update the layout.

In fact, all of this works nicely as long as I don't use a Game.cs class but instead do everything directly in Board.cs (or having the other classes static). What I'm trying toachieve is a good OO implementation, but can't understand how to get the user input on the board back to Game.cs.

Also, I'd really like an answer to the second comment you made. You state it's fully possible but I don't know what to write (or omit).

Thanks again!
BillWoodruff 23-Nov-14 8:16am    
Hi Petter, I happen to be working up an article that I intend to publish here on an MVC implementation for .NET. I decided modeling a game would be a good problem to prototype with.

I'll be happy to share the code with you, and would welcome your feedback and questions; what version of Visual Studio do you have, and what version .NET FrameWork do you usually program with ?

I posted some initial notes I had made as a solution here.

I may not respond further until tomorrow (I'm at GMT +0700) because I'm going out tonight.

1 solution

Here's a kind of overview of how, right now, I view implementing MVC/MVP in WinForms .NET, using as a hypothetical example a "game."

If you conceptualize a play-one-at-a-time "Game" Application using the Model-View-Controller (MVC), or Model-View-Presenter (MVP), OO paradigms: you can "break-out" the Application as:

Model: A one-and-only Class which contains the templates for data-store and behavior required by an instance of the running application (a play of the game). These could be defined in interfaces, virtual, abstract, or "usual," Class implementations.

The Model's objects are exposed only to the Controller. The Model might well include certain resource classes for implementing serialization/de-serialization, or undo/redo, re-play, etc., which can be invoked by the Controller.

Controller/Presenter: A one-and-only Class which gets what it "needs" from the Model, creates or initializes the View(s) based on parameters passed to it by the Model which determine how the View(s) are structured for a particular instance of "game play." And, starts the "game play."

View(s): As "dumb" as possible. Exposed-to, and interact only with the Controller. Pass state/behavior information to the Controller, and the Controller modifies the state/data of objects in the View(s) by calling methods which it injects into the Views.

All of this can be done in Windows Forms. But, implementing this in Win Forms will take you "off the beaten track" in the sense that the "standard model" for WinForms ... what is created when you select a 'New Project of Type Windows Forms Application ... essentially is view, model, and controller, all combined in a one "Main" form.

Note on "static" classes: there's nothing wrong with static classes where:

1. there is one and only one something-or-other, and you wish to constrain the only-one-of in a way that no other instance of it can never be created (singleton).

2. you have an immutable, invariant cluster of functionality (methods) that naturally fit with being organized into a "utility library" (many .NET objects which can be instantiated also expose a set of static methods).

3. you want a repository of data that never changes.

And, there are other uses, as well. I think it's more important to think about what must not be a static class than to think about what should be a static class.

Note that there are many "competing" ways of defining MVC, and MVP !
 
Share this answer
 
Comments
petter2012 23-Nov-14 13:01pm    
Thank you so much for the clarification! This means, I take it, that a lightweight OO approach would still be to ue only a form for input and output, and to have a collection of pieces be instantiated by the form in question - as you said a form is MVC in one place.

The other rather straightforward way of accomplishing this would be to let a Game.cs file control everything and flush out its data (array) to a formdisplaying the board. But if so, how on earth do I send the mousemove events back to Game.cs?

ie:

void pb_MouseMove(object sender, MouseEventArgs e)
{

//I have some code already that figure out which position in teh array is moved to what position, but how do I send this back to Game.cs?
}
BillWoodruff 23-Nov-14 17:00pm    
Well, let me clarify: imho a WinForm "standard model" app is not MVC/MVP because it does lump everything into one container by default. A major reason to use MVP/MVC architecture is to achieve what you might term a high-level "separation of concerns."

Before I send you a prototype to play with, let me ask, again: what version of Visual Studio do you have, and what version .NET FrameWork do you usually program with ?

The other thing I'd like to ask is: are you sure that WinForms, rather than WPF, is the right vehicle for your game; after all, WPF does have built-animations, event-bubbling, vector-everything graphics, a much more robust binding facility.

I dipped into WPF, and didn't particularly get enthusiastic about it, and Microsoft's messing around with announcements that seemed to indicate it did not have a future convinced me not to try and go deeper with it: but, I'm not a gamer, even though the last full-time programming job I had where I was actually an employee was a gaming company ... they got a crazy idea they could do "business" software :)

I'd say for doing 3d you'd never want to use WinForms ... unless there's some whiz-bang library out there now that gives you adequate rendering performance.

Have you looked into WPF and come to the conclusion it's not right for your project ?

In the prototype I'll send you when you're ready you'll see how I go about updating the Controller from events in a View using a technique I call "injection of immutable EventHandlers." Note that while I came up with this "on my own" there's nothing really original about the principle involved, and I am sure other people have come up with the same thing (maybe ?).
petter2012 23-Nov-14 19:45pm    
Hi,

Thanks so much for your kind offer.

I use VS 2010 Premium and also have 2012 Premium installed. Right now I work with .NET 4 Client Profile.


From your reply I guess that there is no really good way of contacting Game.cs from the form. The only possible way I can think about would be to somehow override all listening to user input, so instead of trapping mouse movements in forms, they get trapped in Game.cs instead.
BillWoodruff 23-Nov-14 22:59pm    
Well, I'll send you a prototype compiled with .NET FrameWork 4.0 Client, and see what you think. The fact the Controller creates the Form in my "model" means it has a reference to the Form, and with a reference ...
petter2012 24-Nov-14 2:25am    
Exciting! Thanks a lot!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900