I am hoping to always have a reference to Room as I will use to it to define what should be drawn on the screen(main menus,game rooms) at any given time until the game quits.
I think I may have been unclear. When I say reference, I mean an appropriately typed variable which points to a memory address allocated when an object is instantiated. In the code you showed above, you have a field "room" which has Level1 assigned to it. As soon as your room variable switches to Level2 (in your ChangeScreen method), there are no more references pointing to the memory address where Level1 is. Not only does this mean that you can't access that object again (with no reference to that memory address, it's gone for all intents and purposes) but that object is also eligible for garbage collection (meaning that even if you knew the address, the data stored there could vanish at any time during execution).
There's no hoping on this one. Your design needs an explicit approach for accessing instances of variables whether or not they're drawn on-screen at any given moment. If you allow the active references to expire then your design will need an explicit approach for creating new instances correctly as needed.
I'm creating Rooms this way since, for the actual game, the Room.Update function will use event handlers to check if the user has clicked on a door sprite and change room in Game based on that. I have never used Activator.CreateInstance before and though it has a slew of overloaded constructors, the one I'm using requires a Type parameter. If I'm missing something please let me know.
It's not that you're missing anything so much as you're adopting a complex approach and I'm not sure that you are using (or are planning to use) that complexity for anything. If this is the case, then you should at least consider a simpler approach instead.
As for events, you define those in the class definition just like the fields, constructors, and methods. You then define methods and subscribe them to the event or events you want, and the methods will execute each time the event is raised. You don't need to fiddle with the Activator class at all, and if your plan is to use it only as a static factory class you may want to roll your own instead. There is no reason that you need Activator or any other class just to use events.
Where is Game.Update calling Level1.Update? I guess if I create Room as a separate class I should also call its Update function from Game.Update. Also, are you saying I should have changeScreen in the Room object? This will certainly change to the new room but would it be good practice to dispose the current Room from inside itself? I am passing a reference to the Game object with the variable game but would the following be ok if I am calling changeScreen from say inside Room.Level1?
- game.room = new Level2(game);
My XNA is pretty rusty, but if I remember correctly when Game.Update runs it calls the Update methods of all game components. That's why you were seeing the effect of the Level1 method even though you weren't specifically calling any Level1 methods anywhere in the game loop. Conceptually you should want all active game objects (the ones that will be updating each cycle) to update at the same time, and since XNA already provides an Update method for the game loop that's a good place to do it.
I do not recommend putting the ChangeScreen method in Room. Your instinct was (and is) correct: doing so would be a bad and extremely messy idea. As your sample is laid out, Game is indeed the place where ChangeScreen should be. As your code base changes you should think of which class is "responsible" for managing screens. That may be Game, or it may be some other class.
But invoking Game.ChangeScreen from within a Room object is pretty dicey. My point was that any given Room object shouldn't be doing something like changing which screen is active in the Game object; as your code sample is laid out above this really should be handled by Game. A screen is changed, it does not do any changing of screens. That's a big break in encapsulation and produces tighter coupling than you need and for no benefit.
I didn't think about this so thanks. I guess I will have to create some kind of List/Dictionary in Game that keeps track of items/sprites that have been removed from a room and generate/draw/handle those items in the respective Room based on some status field in the list/dictionary. Possibly one like Inventory for items and another for removed sprites.
There are lots of ways you can do it, and it's a major design decision. It might help to rough out on paper a couple of sample rooms which have the kinds of features that you want the player to be able to interact with (like a take-able item, a flip-able switch, a clue that only appears after some plot event has been triggered) and think about different ways you might represent them as fields of that Room.
I'll suggest using an enum to indicate what kind of object an object is, and to indicate its state (present/taken, on/off, active/inactive). If you're using a list or dictionary you can have a generic Draw method that only renders the objects marked as present (or whatever) and not have to fuss with multiple containers with dynamic contents. But think about it before settling on an approach. Whatever design you choose will still need to have the implementation details figured out and will almost certainly need to be refactored as your project progresses.
I think I should create a ScreenManager for the game since it is essentially a change to different screens based on user input. Having read only the basics of XNA game programming online through piece-by-piece tutorials I thought I should read Microsoft® XNA® Game Studio 4.0: Learn Programming Now! by Rob Miles. Thought it might be a good stepping stone. Would you recommend it? It seems pretty basic(what with trying to teach C# for the uninitiated also) but may be a good way to get a handle on XNA game architecture.
If there are other books you think might be better, please do let me know. It's a pity that most of the info out there either online or in books seems to focus on 3d games or side scrollers. Point-n-click games seem to have definitely gone out of style and they were such fun too.
I don't really like Manager classes for most purposes, and for something like screens and screen changing you don't need one. But there's no reason you can't or shouldn't use one if you want, especially if that makes your program design clearer or more intuitive for you.
I haven't read the book so I can't give you an opinion on how good it is or isn't. If you want to use XNA in the future then it isn't a bad idea to get some material that will help you learn how the guts of it work. For now though, I think that it might be more of a distraction than a help to you. You may end up spending a lot of time reading and memorizing and not so much time programming. Actually coding is by far the best way to improve, far more than reading books, and obviously if you aren't coding you won't make much progress on your game.
The same goes for other books, particularly for the kind of project you're working on now. A key point to remember is that a point-and-click adventure game isn't some totally different animal than a 2D-side scroller or 3D-whatever. Point-and-click is a very simple case of applying the same general ideas about putting pictures on the screen and responding to input, and it's not that the others have information that's totally different so much as that they're focused on techniques you don't need for this.
Like I mentioned before, nearly all of the complexity in your current project will come from getting your hands dirty with program design and planning and producing content. By putting a picture on the screen and having it respond when a part of it is clicked you've already got the capability to do what you want.
Edited by Khaiy, 13 November 2013 - 06:11 PM.