A bigger problem is that when there are no more references to an object it becomes eligible for garbage collection, which may not be what you want for something like a Room in a game (and especially one that might change as the player interacts with it).
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 agree with point number 1. I will create room as a separate class. I didn't think to call room.Draw(and I guess also room.Update) from Game.Update.
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.
2.I'm also not totally sure what you're planning to get by creating instances of Rooms on-demand this way or why you are using Type.GetType to identify the next room to be created.
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?
3. The function calls are well into spaghetti code territory. This too is something that works fine for a small test project but is a nightmare later. Game creates a Level1 object -> Game.Update itself calls Level1.Update (which is fine and normal) -> Level1.Update calls Game.ChangeScreen (this is less fine). Method calls shouldn't be reaching back and forth between distinct objects this way-- you're overly coupled and for no benefit. In general, you want calls to be as one-way as possible in terms of one class containing another as a field.
- game.room = new Level2(game);
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.
4. You may have a particular reason for on-demand generation of Rooms, but I'll urge you to consider an alternative approach. Because a room's contents, triggers, and other components might change as the game progresses creating previously visited rooms via their constructors can be a problem. The player removes an object from a room, for instance, so you don't want the object to be there again when the player backtracks through the same room. You can avoid this with fancy polymorphic constructors, but you might also have something like a container of Room objects which contains an instance of every room in the game and then access and update them as needed. That way you only have to deal with varying room states when saving and loading a game.
As you can see, I have never created this type of game before and none in Windows so I appreciate your help. In fact, the only Windows 'game' I created before this was a program with a Texture2D appearing at a new random position every second in the window and a score and image change each time it was clicked.