Archive for the ‘Design Patterns’ tag

Model View Controller

I learnt about the MVC pattern when I was presented to the book Game Coding Complete. Although the implementation of this pattern on a game development related environment can take some pre-planning, using it allows a much cleaner implementation of your objects with particular relevance for those that have a visual implementation, such as a level or a game token.

I’m saying object, not as an instance of a class, but rather as an abstract game object from a design point of view.

Let’s break the pattern down into manageable parts… after all, that’s exactly what the pattern does.

Model

The model is the data representation of your object. Outside game development, model refers to the data model, usually supported by a database engine. From a game development perspective, model is what your object is, like a level, a platform, the player character, an enemy and so on. If you coded a class that represents something, you have already created a model already.

The main difference with application development is that the data models you use are not persistent and are discarded when they’re not needed.

The idea you should retain game development wise is that your “typical” class design, considering variables, constants and so on is your model, even if this is not 100% accurate from the pattern point of view.

View

The view is the visual representation of your object, which would be any display object, from a movie clip to a bitmap. It is nothing more than this.

Controller

The controller glues everything together! It is the logic behind the actions of your object. Imagine a player character that moves with WASD for the actions Jump, Crouch, Move Left and Move Right. If the player presses W the controller will receive the event and order the view to run the jump animation. Now imagine that some enemy shoots the player character while it is jumping. The controller receives the information that the player was shot, informs the model to subtract damage to player’s life and orders the view to run the hurt animation.

Encapsulating all together

The easiest way to implement OOP on your AS3 game is to simply extend some movie clip to a class and write all code there. With MVC, you need to encapsulate a bit. There are many ways to do this, but this is how I do it.

My controller and view are only one class: the main object class. The view is separated which allows me to have a cleaner interface when I’m working and the possibility of extending or not the view class. This offers a wide range of possibilities since the view class can hold a large ammount of functionality, such as movement patterns, pathfinding and so on or it can simply be the display object.

Controller and view work together regarding data and logic. As I see it they’re not even separarated as a proper implementation of MVC. This often means that a simple state machine is at work, like in the example below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package
{
// This is my controller/model class
public class PlayerController
{
public function PlayerController()
{
// Creates the view
playerView = new PlayerView();
// Code to add it to the level movie clip goes here
}
public function Update()
{
// This method is called from the gameloop
// Depending on the state, chooses actions
switch(state)
{
case IDLE:
playerView.UpdateAnimation(IDLE);
break;
case WALK:
playerView.UpdateAnimation(WALK);
break;
case HURT:
playerView.UpdateAnimation(HURT);
break;
case NONE:
SetState(IDLE);
break;
}
}
public function SetState(newState:int)
{
// No point in doing something that
if (newState == state) return;
// Only does something different if the player is hurt
if (newState == HURT) life--;
// And assigns the new state
state = newState;
}
// Vars ---------------------------------------------------------------
private var life:int = 100; // Hit points
private var state:int = NONE; // Current state
private const NONE:int = 0;
private const IDLE:int = 1;
private const WALK:int = 2;
private const HURT:int = 3;
private var playerView:PlayerView; // The view (displayObject)
}
}

A word of caution

MVC is very powerful, easy and intuitive, but use it when your game asks for it. If you have an object that only needs a couple of methods, by all means, simply extend the movie class or whatever you are extending. Use it to break the complex objects into manageable parts.

Posted: March 18th, 2009
at 12:00am by Vlad

Tagged with ,


Categories: The code of VGS

Comments: No comments


Factory

Factory

Factory

I try to use design patterns to the best possible extent of my ignorance about them. I want to set this straight because like anything found on the Internet, everything here is potentially wrong or a lie. :)

My view on design patterns and so many other things code wise is much more from my own personal perspective and experience, if you want to know more, there’s much more to learn about it, this is just how I see it. 

What is a Factory?

Factory was probably the first I was taught (thanks Diogo!) and one that I used in every single game. From ballons to bullets, every time the need to create objects arises, factory was my choice.

The only purpose of a factory is to create and return objects. From a game development point of view this is useful since the factory is by default reusable code within the game.

If you code a factory class you can use it as a priceless source of objects, from projectiles – as in this example – to enemies or whatever you want really, it’s up to you.

Example

Imagine you are coding a shooter where the player has four possible weapons: machine gun, rocket, missile and mines. Every time the player shoots, the player object would have to decide what to build based on the current weapon. It would be something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package FactoryExample
{
    import flash.display.MovieClip;
    public class NoFactoryPlayerClass
    {
        public function FireWeapon() extends MovieClip
        {
            switch(currentWeapon)
            {
                case BULLET: CreateBullet(); break;
                case ROCKET: CreateRocket(); break;
                // And so on and so forth...
            }
        }
        private function CreateBullet()
        {
            var bullet:Bullet = new Bullet(rotation);
            // Plus, add bullet to level bla bla bla
        }
        private function CreateRocket()
        {
            var rocket:Rocket = new Rocket(rotation);
            // Plus, add rocket to level bla bla bla
        }
        private var currentWeapon:int = BULLET;
        private const BULLET:int = 1;
        private const ROCKET:int = 2;
        private const MISSILE:int = 3;
        private const MINE:int = 4;
    }
}

By the way, the code here is for clarity, I didn’t even run it to check for errors.

What we have here is bad enough by the way. CreateBullet() and CreateRocket() would roughly have the same construction for instance, but it can get much worse. What if you want to use one, some or all the weapons in different enemies or you want to have more weapons?

I’m guessing… copy/paste?

That’s why you should use a factory from start: because you can manage all your projectiles from a single point and you can extend it to have more weapons without duplicated code which you’d probably maintain with a higly dangerous dosage of copy and paste.

This would be our factory class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package FactoryExample
{
    public class Factory
    {
        public static function CreateProjectile(type:int, data:* = null)
        {
            /* Bullets and Rockets only receive an angle from which they'll
          * calculate the vector.
          * Missiles - see FireMissile method.
          * Mines just stand still. */
            switch(type)
            {
                case BULLET:     return new Bullet(data);    break;
                case ROCKET:    return new Rocket(data);    break;
                case MISSILE:    return FireMissile(data);    break;
                case MINE:    return new Mine();        break;
            }
        }
        private static function FireMissile(enemy:*)
        {
            // Gets the angle from the level object to create the missile.
            var enemyAngle:Number = LevelObject.GetAngle(enemy);
            // Creates the missile with the target enemy and the angle.
            return new Missile(enemy, enemyAngle);
        }
        // Projectile types ---------------------------------------------------
        public static const BULLET:int    = 1;
        public static const ROCKET:int     = 2;
        public static const MISSILE:int    = 3;
        public static const MINE:int    = 4;
    }
}

In this case, the factory is a class that offers static functions, so you don’t have to instantiate an object from the Factory class. Note that the CreateProjectile receives the type (duh!) and some other data that can be anything or nothing at all.

The purpose of this is to pass angle to bullets and rockets, the target enemy to missiles and nothing to mines.

So now, any class that would need to fire a projectile would need a method like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package FactoryExample
{
    import flash.display.MovieClip;
    public class WithFactoryPlayerClass extends MovieClip
    {
        private function Fire()
        {
            var data:* = null;
            switch(currentWeapon)
            {
                case Factory.BULLET: data = rotation; break;
                case Factory.ROCKET: data = rotation; break;
                case Factory.MISSILE: data = targetEnemy; break;
            }
            var projectile:* = Factory.CreateProjectile(currentWeapon, data);
            // Do more stuff with projectile
        }
        private var currentWeapon:int;
        private var targetEnemy:*;
    }
}

And to end…

Imagine that the enemies in your game have a predifined weapon… instead of a bunch of code you will only need one line in you enemies classes:

1
var projectile:* = Factory.CreateProjectile(myWeapon, otherData);

It can’t get any easier than this!

I hope this helped you sort how factories can help you. Take into consideration that you can use a factory with pools of objects, this is an example that creates all objects on demand. There’s a lot more that can be done, but the rule of thumb is: a factory can be the answer to many object creation needs a bit everywhere, but in game development it really shows what this design pattern is capable of.

Posted: March 9th, 2009
at 12:00am by Vlad

Tagged with ,


Categories: The code of VGS

Comments: 4 comments


    Newer Entries »