Best Practices for Code Organization
Best Practices for Code Organization
- Subject: Best Practices for Code Organization
- From: Alex Hall <email@hidden>
- Date: Fri, 27 Dec 2013 11:19:27 -0500
Hello list,
I am continuing to work on my audio game for the Mac. Audio games are a genre of games for those who cannot see; these games use audio to indicate obstacles, enemies, and other game elements. Anyway, as with most games, a huge part of the experience is keyboard commands, which means a keyboard listener, which means an NSView object. I'm not sure, though, where all of this should go - keyboard listeners, sound manager, view controllers, and so on.
My project is currently:
AppDelegate: uses applicationDidFinishLaunching to set up the gameController, NSWindow (Apple gave me that one), and other initialization. It runs the main game loop. In the ApplicationShouldTerminate method, I exit the game loop and return.
BBOpenALController: this library was given to me for managing OpenAL. It sets things up to play sounds, lets you load, play, pause, move, and adjust sound sources, and so on. It knows nothing of the rest of the game, which is how I want it, of course. My audioManager object in the GameController is an instance of this.
GameController: my plan is to put most of the game-specific logic here. Currently it instantiates a BBOpenALController object and plays a sound. It then enters a loop, where the sound is moved in a circle. This was just a test to be sure everything was working and that my NSTimer was going to give me good sound panning resolution, which it seems to. As things move ahead, though, this will, I imagine, be the hub. It will know about all the views, the player object, the map (which is a view in itself), all the sound files and other resources, NPCs, and anything else. All these items will be in their own classes, but the GameController will know about them and control them all.
AudioMenu: this is a subclass of NSView and currently contains only the keyUp method, as described above. I plan to add a dictionary of menu items, each a dictionary in itself with several properties for each men item. The arrow keys will call methods to move up and down in the menu, the enter key will call the selected menu item's callback selector, and escape will close the menu.
Map: this is not yet built at all. When it is, it will have a method to parse an xml file for map building instructions. It will also include movement commands, tile triggers, and more. Keep in mind that this is an audio game, so the Map will be doing a *lot* of sound work: placing sounds, cutting them off, managing barriers (which will affect sound occlusion), and more. It also needs to track the player's position.
ViewController: this has methods to draw UI elements, add and remove subviews, and other UI things. It has a reference to the app's main window (or maybe it creates the window, I don't yet know). For anyone asking why I'm not using IB, Apple has *still* failed to make adding actions to UI elements accessible to Voiceover. I kept hoping they would fix this, but we are now on 5.0.2 and I still cannot fully use IB.
Player: has a bunch of properties for the player (health, inventory, speed, armor, that kind of thing). This is also not yet written.
Weapon: inflicts damage on other objects and is meant to be subclassed. The Player will have one or more of these, probably stored as objects in a dictionary, so that methods like "fire", "reload", and more can be called on whichever weapon is selected. Weapons also have several sounds associated with them. This, too, is not yet written.
So, that's the general idea. Now, how do you all suggest this be organized? Much of it is inter-related, which is where I am unsure. Take, for example, the player pressing up arrow to step forward.
1. Up arrow is pressed, and is detected by the Map object's keyUp method.
2. The keyUp method calls the Map's moveForward1 method, and now we have the difficulties. What needs to happen is:
A. If the user cannot move forward, an impact sound must play and the position change to be as close to the barrier as possible. This would happen if the player were walking at a wall, for instance.
B. The player's speed needs to be known, as that speed will vary based on a number of factors (terrain, health, and how much the player is carrying, for instance).
C. The player's position must be updated based on that speed.
D. The OpenAL listener's position must be updated to reflect this change, so that sounds will pan and adjust accordingly.
E. A footstep or other movement sound must play at the listener's new location.
F. The Map object must look at the new position to see if anything should happen (any location-based triggers).
The problem is that sound playback is through GameController's soundManager object, as is the listener position; the map location is in the Map object; the player's coordinates are in the (as yet unwritten) Player object, and the properties that affect the new location (AKA speed) are also in the Player object. This will be a common problem, so I want to figure out the best way now. For example, if the player picks up an item, the item's sound needs to stop, the Map to update, the player's inventory to update and a pickup sound to play, and there again we have several different objects needing to talk to each other. Similarly, firing a weapon plays sounds, changes the properties of the weapon (ammo count), can impact objects on the map… You get the idea.
So, how do you all recommend this be organized? Should the GameController be "god" and know about everything? Should I pass references around to let objects modify each other (seems like a bad idea, but it is an option)? I'd like to stick to MVC as much as I can, but so many parts need to reference each other that doing so seems difficult. I know I'm far from the first to run into this, so I'd love to know what models others have come up with. Thank you in advance.
Have a great day,
Alex (msg sent from Mac Mini)
email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden