View Full Version : [AS3] Setting up classes and the core engine
Skribble
March 21st, 2010, 08:06 AM
So I'm new to the whole "classes" thing. I've been latching on to AS2 for forever, but having started developing on the UDK I have been forced to learn about classes, states and the like. It's a little daunting but Im getting the hang of it.
From what I understand you create a class for object types in your game, and you can create subclasses that extend another classes properties. e.g.: neutral, aggressive and friendly NPC classes all extend the "controller" class which deals with things like movement and gravity.
I'm used to cramming everything in to functions. Loading levels, characters, special effects, sound management, enemy ai, etc. I did it all through functions in one frame. My mind is not accustomed to having all of my code separated in to handy chunks like classes, so I can't really get my head around how to construct a basic engine (lets say platformer).
So I just wanted some personal input. How do you set up your engine? Do you have a main "controller" class that you subclass for other classes? Do you use classes to attach level assets, or do you leave that to the main "engine" in your FLA? Do you use classes for special effects? Sorry if I'm not making too much sense. Classes are a little abstract for my usual pattern of programming.
Thanks in advance!
Brendan
TOdorus
March 21st, 2010, 02:27 PM
Well my main classes are management classes:
Main (holds every other class and the main update cycle. The main update cycle holds a switch to update Level or Menu)
Factory (holds all functions that need a definition and return a in-game object)
Level (= model. Holds the gamestate and update functions)
Menu (holds the menustate and buttons. Basicly an GUI for the main class)
View (gathers information of the model and blits it to the screen)
Hear (manages sounds. Has functions to fade in/out music etc.)
Constants (holds all the constants, like 1 = EnemySoldier and 1 = MenuMusic)
Preloader
FrameRater
Optional
LevelEditor
CharacterEditor (most games don't need this)
Than per game there are different classes that exist in the model.
Like:
Character
Infantry
Soldier
Commando
Vehicle
Jeep
Tank
Weapons
Guns
SMG
Minigun
Bullets
lightBullet
heavyBullet
Tile
Tree
Grass
My folder structure is actually like that, so lightbullet.as would be in the Weapons.Bullets package. This keeps things organised, especially when working with a program like FlashDevelop.
What I also find valuable is to have sperate AI classes. This will look something like this.
//
//CHARACTER CLASS
//
public var AI:ai = new OffensiveAI(this)
//
//LEVEL CLASS
//
public function update():void {
var CHARACTER:Character
var c:int
var length:int = characterList.length
for(i = 0; i < length; i++){
CHARACTER = characterList[i]
CHARACTER.AI.update()
}
}
//
// MAIN CLASS
//
var CONSANT:Constant = new Constant ()
var updateMode:int
private function update(EVENT:Event){
switch(updateMode){
case CONSANT.LEVEL:
theLevel.update()
break;
case CONSANT.MENU:
theMenu.update()
break;
}
}
the AI class will read the properties of the Character when it needs to. For example I have a maximum jumpheight property in my Marshmellow characters for pathfinding.
Skribble
March 21st, 2010, 11:57 PM
Just awesome. Seriously, many thanks from me to you.
This has pretty much cleared up any confusion I had about structuring classes.
I'm sure I'll have plenty more issues once I continue on to the actual coding haha, but I'll cross that bridge when I get there.
Again. Thanks a bunch! :)
dandylion13
March 23rd, 2010, 11:54 AM
Hi Skribble,
You might also want to do some research into the Model View Controller design pattern. It can solve a lot of our game architecture headaches in a very elegant way.
Once you understand it, you can break each game component into its own MVC system. You can then also structure the entire game as a big containing MVC system.
TOdorus
March 23rd, 2010, 12:28 PM
I try to practice MVC too, but isn't it much of a hassle to do this for every game component? As I understand it was designed with databases in mind.
For example I use a movieClip for my menu, which will contain my buttons. Now my mainMenu class will assign listeners to these buttons and update the movieClip for submenu's, volumesliders etc. Is this MVC strictly speaking? I mean, the view and control seem to be in the movieClip while the model, part of the view and part of the control seem to be in the mainMenu class.
dandylion13
March 23rd, 2010, 12:47 PM
Hey Todorus, yes, it's sounds like that's pretty much MVC :)
It's actually quite acceptable to have a combined View/Controller class... it's maybe even the norm for Flash development. Sounds like that's what you're doing. I also do that for many things, like sound and music effect classes, where the view and control are so tightly linked it seems crazy to separate them.
You're right about MVC and databases. But if you think about it, a game is really just a big database, isn't it? What you see on the stage is just a visual representation of game data. (I don't' mean database in the sense of a big MySQL type system, but as a simple storage container, like an array or Object with properties that can be accessed or changed).
Maybe this makes sense to me because the first games I ever made were text adventures written in BASIC. In text adventures, the whole game world is data stored in arrays, and the world is created by deciding which data to display or change based on user input. So I had that construct in mind when I moved to video games, and I find it still pretty much applies.
TOdorus
March 23rd, 2010, 02:30 PM
Yeah, that's the problem with using movieClips I guess. It used to be part of Flash's user friendly paradigma that a movieClip should have all those functions. It does make checking for the mouse a lot easier though :)
I use blitting in my game engines itself so they're pretty much pure MVC. My main update usually looks like this
switch(MODE){
case CONSTANT.GAME:
theLevel.update()
theView.update()
break;
}
Than I have my input class "theInput" which holds the mouse position and booleans for every key I use (WkeyDown:Boolean for example), which would be the control. As it uses listeners it's pretty much seperated too. So basicly theLevel reads the user input from theInput and handles every interaction for the update. Then the view reads all the variables from theLevel and updates the canvas. All nice and seperate and you can change stuff in a class without screwing things up in another one most of the time. Sound can be also be handled this way, to make it part of the view class, but I choose to make it more event based.
I think this is also possible with movieClips. My first dabble into Flash actually works similair to a blitting engine where scrolling is concerned.
Every object has it's x and y properties in the model. The view update then calculates the position relative to the upperleft corner of the screen. For every object check if it should be onscreen. Finally check if it is onscreen already and remove it from/add it to the display if necessary and update the position of the movieClip when onscreen.
The problem you run into with that system is with animation. At what frame is the animation? I use a getFrame method on my characters, which determines what animation should be played and what frame it currently is in. These actually are in the model, but it has no function in the model. It's there because the view needs that data to properly work. This is the reason why I choose not to do this when sound is concerned. Every character would need a flag (a integer which corresponds to a sound), to show that it has started a sound or not. I find this a bit of a hassle, but I may switch to it in the future.
So in the end: as far as a game engine is concerned I agree that it is a good idea to look at it as a model, a container which holds and updates all the game data. The main advantage is that when you run into a bug, you know where it is at. Each manager class has it's own responsibily so to speak.
But what is your setup dandylion? Scribble and I may pick some things out of that design as well. I am hoping to see some other forum members jump in here and see what they have to say about this though.
dandylion13
March 23rd, 2010, 03:41 PM
Hi Todorus,
Your setup actually sounds almost identical to mine, just a few minor details are different and I think we use different terms, but it's pretty much the same :)
It makes sense to have an input class if you have a complex UI. I think of it as a "UI View/Controller". That's good old-fashioned MVC :)
For structuring a whole game, this is what I do:
- I have a model class that holds all of the game data. All the data for the game objects and level data. It includes all the "visual data" like x,y positions and BitmapData, etc. It also includes references to the actual level Sprites or Bitmaps (for blit engines) that display the objects on the stage. (In bigger games I'll create a separate level-model class for each level, and a game-model class that handles global things like the score.) the game model can have methods that track the score and other data to decide when to switch levels or end the game.
- I feed an instance of this model class into a game controller and game view. The view adds the game Sprite or Bitmap to the stage and creates buttons and listeners. The game view either handles button clicks itself, or sends it to a UI controller if it's a complex UI. The game view also switches levels and displays menus and game screens based on the status of the game that it reads from the model. The game view doesn't actually handle the display of the game objects on the game screen itself, because in my mind that involves making game logic decisions which should be the responsibility of the controller. I think that's where your system is a little different than mine. I also haven't done any games with sophisticated blit engines yet so I'm sure you've found some good solutions to problems that I haven't had to consider yet.
- The game controller reads the model data and basically runs the game logic. Adding and removing objects on the stage are done by referencing the level Sprite or Bitmap in the game model and updating arrays in the model that store them. I'll usually also create a sound controller and collision controller class to offload those responsibilities, because they can become quite complex. I instantiate those in the game controller, and they each have references to the game model.
.. so this is pretty complex! But it's all based on adhering pretty strictly to the MVC. This helps because, like you said, if something goes wrong you know where to look. It also scales really well. It works for tiny games and huge ones. And it's especially good if, like me, you never plan anything and your tiny game accidentally becomes a huge one ;) It's also content neutral, so will work for any kind of multimedia engine, not just games. Plus you can swap out a different views, models or controllers to try radically new things or create completely new games without breaking the whole engine.
But I think it's more or less when you're doing Todorus, we've just sub-divided things in a slightly different way. I could see occasions where I could break things down in a similar way to what you're doing, and your terms actually make more sense because they're game-specific.
Skribble
March 25th, 2010, 03:04 AM
Thanks for all the input guys; especially the detailed descriptions of how you personally have things set up. I've started reading up on MVCs and it seems like a really handy way to organize script. It would be good to finally make a versatile engine that I could just add to, instead of coding things from scratch all the time.
Thanks again. A really huge help!
Brendan
dandylion13
March 25th, 2010, 12:59 PM
It would be good to finally make a versatile engine that I could just add to, instead of coding things from scratch all the time.
Yes, that's what I do. Whenever I complete a project that I think was well organized, I strip it down and create a set of template files for it. (Just classes and general properties set up in advance). It makes it really quick and easy to code into it.
Powered by vBulletin® Version 4.1.10 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.