Why can’t we just get along??

31 01 2009

Weekend is here and I’m going away. Still I spent an hour or two tonight and move code around, which, if you’re into game programming, you know that you will do often. Suddenly you just realize that the code should be somewhere else, in another class, called another thing. Hopefully it will lead to a somewhat cleaner and more logical code. Sometimes it doesn’t :(

There are a some things with PV3D that I really don’t understand why they did like they did. Take size as an example. This is the first time ever (EVER) I stumbled apon a 3dobject that cannot tell me how big it is. It moves around in a 3dspace uses exact coordinates to travel. Still there is no sign of the object knowing what height it has or how wide it is??? There is this bounding box parameter inside the geometry param so it wouldn’t be that hard to implement a recursive check for size both before and after transform. Am I missing something? Why dont I extend the DO3D then and put the functions in there myself? Well, as the whole PV3D is built on DO3D it will not use my extended class so it’s no use.

“So why don’t you just hack the original class then. Just put the features in there?” Well I actually did, and removed it , and did it again and finally removed it  because I know that PV3D is always under development. I am a news freak and always want the latest build and it would be a drag just to update the library manually, putting in my beloved code, each time I update PV3D. Also I wouldn’t be able to write this kind of blog as I cannot expect every single reader out there to hack their basic library classes just to get my examples in here to work.

No, I’m satisfied with just cursing.  :)

So? What’s the deal with layers anyway?? I promised to show you and as I’m leaving in a few minutes, this is an excellent time to bring up that subject.

To be able to draw 3D objects correctly on the screen, the renderer always draws the thing that is furthest away from the camera first. That is logical because if then something appears in the way that is closer to the camera it should overwrite the object far away. But there are times that you actually want to force the renderer to draw the objects in another order thatn it’s default behaviour. This is where layers come in.

In the case of this game, I will use viewportlayers for 2 reasons. 1: the annoying Z-fighting problem and 2: Visual effects.

The Z-problem is a little thingie that has been haunting the 3D world since the beginning of time. As I mentioned earlier the renderer automatically renders the furthest objects first. But how does it know that it is furthest away? Well EVERY single triangle in the 3D-world has got a centerpoint (yes right in the center of the 3 vertices drawing the triangle) and the triangle itself then can calculate how far from that centrepoint it is to the camera. It’s a simple question of distance (and math).

But what happenes if the triangle is a big ass giant triangle? Well it is still the center that decides when it will be drawn. Our arena ground in the game is a perfect example!! It is built up with big ass triangles!! So if our car happens to be on a place on the ground where the centrepoint is behind it. The scene wil be drawn as normal BUT if the car (Defender) moves away at places itself in the ground far away it as a very big chance that the centrepoint is now closer to the camera that the Defendertriangles are. Then the renderer will draw the Defender first and then the ground, causin the defender to suddenly disappear (be drawn uderneath the ground).. hmmm damn.

So now layers is our saviour. We kind of “put” all the objects in different layers and then the renderer will render ALL objects in one layer and then continue to the next layer that has a larger layerindex.  Problem solved!

Effects, we’ll take when we get there. You just think about all cool effects you can do with viewportlayers… mmmm…   in front, in back, in front. Amazing huh? no? Tutorial coming up!

Advertisements




Important things to know when creating graphics for PV3D

30 01 2009

Behind this blog a lot of activity is going on, assetswise. The best thing with developing a game by yourself is that you can actually put something aside for a while and do something completely different. Tired of coding? Well grab that keyboard and create some music then? No, what about modelling? Not today, huh? Well, there’s always, texturing, level design, 2D-art, sound effects, visual effects, PR, in game dialogue, websites… etc etc.
So I’m creating a lot of content for the game and want to share some fundamental tips when it comes to modelling and texturing for PV3D.
First we need to realize that PV3D is way behind when it comes to 3D performance. We all probably know the reasons why and the fact that it is a great new experience for the flash environment doesn’t make it fresh and new as a 3D experience. Even back when 3dfx released it’s first Vodoo chip more than 13 years ago the computer could render polygons much faster and more accurate than PV3D is able to do. Still this doesn’t have to be something genuinly bad. Personally I see this as a wonderful creative challenge to actually be able to trick and cheat my way through PV3D to push the limits so the endresult still can intruige, shock and amaze users.

There are several PV3D users out there that compare the whole situation with the old demo scene from the C64, Atari and Amiga eras and I agree.

Now, then. Question is what CAN PV3D handle and how do we create optimized assets for the engine?

Let’s start with modelling:

Every triangle counts! Its obvious that it does but still people are really bad modelling optimized 3Dmodels. Even if you think you cannot remove any more polygons without distorting the whole model, you probably can. Let’s take my car as an example:

defender This model was created for another engine and even though it runs smooth as it is now on our testscenes , the model is way too detailed both for the game and for PV3D. At the moment the jeep is built up with 1108 triangles and a lot of them are very very useless. We always need to consider how close the camera will come to the unit as it’s closest and calculate whether some details are worth it.  The two crash pipes on top themselves use way too many polys and could easily be built up with 2 or 3 planes facing upwards. As the game will be a top viewed game I can remove all polygons underneath. There will be no physics in this game so the jeep won’t roll around showcasing whats underneath.

Rounded areas is always a problem so even if we cannot have square wheels we could easily take a few of the polys there. Remember that the camera will be rather zoomed out most of the time.

You can always keep the detailed model as well as might want to try a LOD technique as the camera moves in. LOD (Level of detail) is working in the way that when the camera gets closer to an object, the object switches to a more detailed model whenever the details will be more visible. In this manner you can save a lot of resources when the camera is zoomed out. I think I will try this technique in the game. Also remember to check for loose vertexes and faces when you are creating your model. In several 3D-apps there are a few automatic optimizefunctions that both removes unused vertices and also tries to optimize the model (based on angles). You could come very far with these features.

I cannot stress enough how important it is to keep the polycount down. There is nothing worse than realize in the middle of your development you will only be able to spawn 3 models and 2 bullets at the same time in a shoot’em up or the gameplay will be ruined by a framerate at 6 fps. Even though it runs smooth when you test your models, it might not do that when there are 3 in there + AI code + 2Dfx + HUD + networking etc etc. A lot of games has gone down the drain just because it lagged too much and the joy of creating the game just disappears.

Now there is another problem with PV3D. As PV3D is not able to set perspective correctly on each face, it “fakes” perspective by “skewing” the triangles. It works like a charm when a lot of triangles are involved and when its facing the camera but if you eg create a plane  with no division (only 2 triangles) and then rotate it on the y-axis you will clearly see a great distortion of the texture when ever it is facing any of the sides. This is not happening in a normal 3D-engine but is a terrible must in PV3D due to what we are given through Flash. This means that certain flat surfaces that easily could be built up with 2 triangles not instead requires a lot of polygons not to distort terribly.

This will be a huge problem for the arena ground in my game so I will think about a solution.

What about texturing then??? Well, how you handle textures in PV3D are more forgiving than triangles but if you try using a texture (BitmapMaterial) compared to a ColourMaterial you will of course see a huge difference in performance. But still.. we want textures, right?

texture_sizetest21

Above you can see the texture for the defender cannon. The difference between the 3 is the size of the texture (from left to right 128×128 , 512×512 , 256×256). Comparing the left and the right cannon you can see that the texture is of course smoothed out with 128×128 and there are more details in the 512×512 one. Same here is the question, how CLOSE will the camera get to the object? At the same time you must ask yourself, is it worth it?

I know that in this game during gameplay, the camera will be very much zoomed out just like the pic below:

hudSo in this case, any big textures are just a waste om memory and processor resources that I could use for a lot of other things. Still, usually in PV3D projects, I see a LOT of too small textures giving you that squary pixel textures. That aint cool! Using a 256×256  or 512×512 texture is more a question of memory than really that much processor so is you are seeing too many and too big pixels, try a bigger texture.

The classic way of deciding which size the texture should have is to make it on any size of 32,64,128,256 or 512. Now, (correct me if I’m wrong), believe that is a heritance from how the arcitechture of the gpu’s were built and one were always recommended not to use any bigger than 512×512. I do not believe that’s the case for PV3D as there is no GPU Hardware acceleration involved here so we’re using the normal memory. Still, going over 512×512 shouldnt be necessary unless you are working with big environments (eg the Arena ground in this game).

This texture-tips has only been about the “diffuse-maps” (the colour that are visible on the model) there are a lot to be covered when it comes to textures and materials that I probably will bring up later on in this blog. I’m not sure if any of the shaders will be used in the game but I would still like to mention them both for experience purposes and to uphold this blog as a tutorial blog :)

Now go and create some assets! Here’s some wip of mine:

djn2sallysizecomparison





Links here:

29 01 2009

The compiled swf-file now looks like this (click on the movie to interact with keyboard and mouse)

And the sourcefiles can be downloaded here: (you lazy bastards!)

Thank you for reading and please help me out with comments, critics and questions if someting is unclear (or I’m just a stupid Swede).

/Andreas





Huge update now. Are you ready?

29 01 2009

Problem with writing a blog about such a creative thing as developing a game is that things happens very fast and sometimes very, very much.

It’s a good thing of course. I don’t have to bother about if I do have something to write about but already now understand that it is very dificult to find a balance between documenting it all carefully but pulling the brakes too much and getting all those creative ideas down on paper (yes digital ones) just to look back and see if they (you) ever will be able to understand and follow what just happened.

I still have decided that some parts of this game must be covered in shadow. not because I’m scared that you’ll exploits my darkest secrets but just the fact that they are not really interesting when it comes to the core subject: building a game with AS3 and PV3D. Remember this carefully now: IF you find yourself saying: “whoaa, how did he do that?” or “hey?? Where did THAT suspicious and geniously functional class come from?” it is just normal. I won’t cover every class and function anymore. Still remember THIS even carefullier: If you are very much interested in finding out exactly HOW I did it it or where you could find that seductive  class of mine, just write me a comment and I’ll try to fit it in.

Why did I tell you this right now? Because I’ve been coding today :) I will from now on try to pack all my source into zip-files so you don’t have to write down every stupid line in here. Still, I believe that reading and writing yourself (and destroying the code with reckless experiments) is the best way to learn.

THIS IS WHERE WE ARE NOW

Let’s see what we got:

First of all. A lot of previous classes has been updated and changed due to.. well new thinking I guess.

The things a just want to sweep away at the moment is the MeshManager and AssetsLoader classes I created. AssetsLoader is called at the init start of the whole game and handles all loading of all assets (duh!).  MeshManager is the Managerclass I have to retrieve the meshes when I need them just by sending in an id so you will see me call this class from time to time so you only need to know that I send in an ID and get a DisplayObject3D.  Yes, it’s kind of a magic box ;)

Let’s then skip Main.as (where all assets are loaded). You can look at it in the zipfiles.

With loading out of the way the View3D is a lot cleaner now. Let’s take a look at that instead:

package
{
    import flash.events.Event;   
    import managers.MeshConstants;
    import org.papervision3d.lights.PointLight3D;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.view.BasicView;
    import org.papervision3d.view.layer.util.ViewportLayerSortMode;
    import se.xcom.framework.managers.MeshManager;
    import units.*

    public class View3D extends BasicView
    {
        private var defender:AUnit
        private var light:PointLight3D
        private var topDepth:uint = 100

        public function View3D()
        {
            super();

            initScene()
            createGround()
            createDefender()

            this.startRendering()    // never ever forget to start this one
        }

        private function initScene():void
        {    // inits all basic stuff like camera, light and.. stuff

            // sets ViewportLayers to sort using index-numbers. (just like the DisplayList)
            viewport.containerSprite.sortMode = ViewportLayerSortMode.INDEX_SORT;

            this.camera.y = 3060
            this.camera.z = -4001
            this.camera.zoom = 230 // now look here! you can zoom!

            light = new PointLight3D()
            light.x = 1000
            light.y = 5000
            light.z = -6000
            scene.addChild(light)
        }

        private function createGround():void
        {
            var tGround:DisplayObject3D = MeshManager.getInstance().getMesh(MeshConstants.GROUND)
            tGround.scale=25
            scene.addChild(tGround)
            // Putting the ground in it's own ViewportLayer. Also setting an index-number to it.
            viewport.getChildLayer(tGround, true).layerIndex = ++topDepth;

        }
        private function createDefender():void
        {
            defender = new Defender(0)    // creates our Defender. '0' is the ID and could be any number at this stage of development.
            scene.addChild(defender.mesh)    // News: I removed the DisplayObject3D extension on AUnit so the mesh needs to be added
            viewport.getChildLayer(defender.mesh, true).layerIndex = ++topDepth;    //The unit is rendered on its own viewPortLayer.
        }

        override protected function onRenderTick(event:Event = null):void
        {
            defender.transformUnit();
            super.onRenderTick(event);
        }
    }
}
The greatest news in here is that Defender only takes an ID and nothing more. Everything else (the composition of components) is handled within the specific Defender-class (as Defender is a unique unit and will look and behave in just one way). We’ll look into that one soon.
The other news is Viewport-thingie. As I mentioned earlier, the viewport is like the TV-screen that shows exactly what the camera is looking at (filming). But the viewport does have layers, just like every flash user are used to with simple 2D. As a default every object in the 3D world is put into the same layer and therefor are rendered at the same time. But just like the 2D layers, you can move some objects to another layer and that layer will be rendered AFTER the layer underneath is finished rendering. The end result is that all objects on the layer “above” will be fully visible and not being overwritten by an object from the previous layer. Just learn what it is. I will come back to the question WHY we would want to do such a thing.
Oh and I placed a ground there too. This is not really news, you know how to do that already. But in the end that is what will be visible as progress (not te thousands lines of code behind the rest of the update :D)
package interfaces
{
    // this is the Interface for all controllers, be it local, ai or remote via multiplayer.

    public interface IUnitController
    {
        /*     each Controller gives away a ControlMatrix-object containing at least the following parameters:
        *    horizontal:         think of this as left and right (-1 1)
        *    vertical:             think of this as up and down (1,-1)
        *    newLastPosition:    if true then these values are used: , posX:, posY:, rotation:
        *    mouseDistX:            how far the mouse has been moved horizontally since last update
        *    mouseDistY:            how far the mouse has been moved vertically since last update
        */

        function getControl():Object    // gets the control object
        function updateControl():void    // updates the calues and creates an object
    }
}
Oh look! I updated the IUnitControler interface. Some people will now be saying “AAAHH BUPUPUPUPP. You are not supposed to change an interface like that. The gang of four told us that…” – Screw you I say! (not the Gang Of Four, I like guys with open-source-beards) The game is still in design state so I redesign my interface as much as I want to. “Why can’t you change interfaces” might some other guys now say. -Shut up! You are wasting blogspace! Let’s talk about my new interface.
Most important with the update is that there is now 2 functions that must be in a controller. Added is an UPDATE function that actually recieves all control data and creates the controlobject that will be sent. This has unloaden the burden for the getControl() function that just passes that object out. Main reason why I did this is that it seems like one unit might need to get the latest update several times within one frame so just getting the same object will not only save time but also the new object parameter: mouseDistX and mouseDistY will not screw up. They just show how far the mouse has been moved since last update.
package controllers
{
    import flash.ui.Keyboard;

    import interfaces.IUnitController;

    import se.xcom.input.ArcadeKeyboard;

    public class LocalController implements interfaces.IUnitController
    {
        private var controlObject:Object
        private var key:ArcadeKeyboard
        private var lastMouseX:Number
        private var lastMouseY:Number

        public function LocalController()
        {
            key = new ArcadeKeyboard(Main.scope)
            lastMouseX = Main.scope.mouseX
            lastMouseY = Main.scope.mouseY
        }

        public function getControl():Object
        {
            return controlObject;
        }

        public function updateControl():void
        {
            // getting up, down, left, right from keyboard
            var tVert:Number=0
            var tHoriz:Number=0
            if (key.isDown(Keyboard.UP))
            {
                tVert++
            }
            if (key.isDown(Keyboard.DOWN))
            {
                tVert--
            }
            if (key.isDown(Keyboard.LEFT))
            {
                tHoriz--
            }
            if (key.isDown(Keyboard.RIGHT))
            {
                tHoriz++
            }

            // calculating movement of mouseX and mouseY
            var mouseXdist:Number = lastMouseX-Main.scope.mouseX
            var mouseYdist:Number = lastMouseY-Main.scope.mouseY
            lastMouseX = Main.scope.mouseX
            lastMouseY = Main.scope.mouseY

            // creates new controlObject
            controlObject = {vertical:tVert , horizontal:tHoriz , mouseDistX:mouseXdist , mouseDistY:mouseYdist , newLastPosition:false}
        }

    }
}
The new LocalController now looks like this. Any questions about that? no? good (what, you wonder about that Main.scope call??? check Main.as in the zip-file and leave me be)  Moving further… to.. the fancy…
package units
{
    import controllers.*;

    import interfaces.*;

    import managers.MeshConstants;

    import org.papervision3d.materials.ColorMaterial;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.Sphere;

    import se.xcom.framework.managers.MeshManager;

    import transformers.*;

    import weapons.*;

    public class Defender extends AUnit
    {
        private const CANNON_ANGLE_MAX:int = 75
        private const CANNON_ANGLE_MIN:int = 10

        private var mCannon:DisplayObject3D
        private var mBody:DisplayObject3D

        public function Defender(id:uint)
        {
            var tMesh:DisplayObject3D = initMesh()
            super(tMesh,new LocalController(),new CarTransform(9,0.85,0.2),new MissileLauncher(),id);
        }

        private function initMesh():DisplayObject3D
        {
            // in this function I fetch my meshes with my newly built Meshmanager
            // unfortunately the meshes are not centered nor scaled correctly
            // so I need to tweak them a lot before they are correctly placed.
            // There are 2 meshes. One body and one cannon. They are all a part of
            // “wholeMesh” that is sent to AUnit construcor.
            var wholeMesh:DisplayObject3D = new DisplayObject3D()
            var tMan:MeshManager = MeshManager.getInstance()
            mBody = tMan.getMesh(MeshConstants.DEFENDER)
            mBody.rotationY = 180
            mBody.z += 165
            mBody.x += 180
            mBody.scale = 50
            wholeMesh.addChild(mBody)

            // to be able to rotate my cannon at desired axis, I create a DisplayObject
            // and puts the cannon inside it. Rotation pivot point is always 0,0,0 so I just
            // move my cannon inside so itgets the desired pivot point.
            mCannon = new DisplayObject3D()
            var tMesh:DisplayObject3D = tMan.getMesh(MeshConstants.DEFENDER_TOWER)
            tMesh.rotationY = 180
            tMesh.z -= 30
            tMesh.x -= 70
            tMesh.y += 35
            tMesh.scale = 50
            tMesh.scaleZ = 60
            mCannon.addChild(tMesh)
            mCannon.y = 85
            mCannon.x = -185
            mCannon.rotationZ= 8
            wholeMesh.addChild(mCannon)

            return wholeMesh;
        }

        //
        override public function transformUnit():void
        {
            // Here I call the same function at the parent class AUnit.
            super.transformUnit()

            // get already updated control object.
            var tObj:Object = control.getControl()

            // set cannon rotation by mouseY movements
            mCannon.rotationZ += (tObj.mouseDistY/10)

            // set cannon angles within boundaries
            if (mCannon.rotationZ >this.CANNON_ANGLE_MAX)
            {
                mCannon.rotationZ = this.CANNON_ANGLE_MAX
            } else if (mCannon.rotationZ < this.CANNON_ANGLE_MIN)             {                 mCannon.rotationZ = this.CANNON_ANGLE_MIN             }          }     } }[/sourcecode] So here it is! The updated and enhanced Defender-class. Now a lot more code has been added, not only new features but a lot of the "building up a unit" will be inside the final unit-classes like this. Let's go through it and see if we can learn something new. First of all you can see that I override the transformUnit function that is defined in AUnit. I actually tells Flash to go with this new function instead of AUnit’s old one. Now, there are important code in AUnit’s function that I need to be run so I just start with calling super.transformUnit meaning that I call and run the function transformUnit() in the parent class (super class).  The rest of the function rotates the cannon angle due to mouse movements (try the compiled swf above!).

The other thing that I’d like to mention is the way I set the pivot angle of the cannon. If you are familiar to rotating with AS3 since before this is no news to you but everything is rotated using 0,0,0 (origo) as the pivotpoint. So now when I doesn’t want that as my pivot I need to put the cannon inside another DisplayObject3D and then move it around so that the point of rotation winds up on exactly the local 0,0,0 in that new DisplayObject3D. Then finally I rotate my whole DO3D and voila, my cannon is rotating just like it should.  A few other small tweaks here and there are made in the classes but I guess you can look at them yourselves. I just post this post now (of 1803 words.. blog record?) and Post a new one when the compiled SWF and the source is ready for download.

(1844 now)





ShotEngine – all bullets in one place

29 01 2009

In the same way all units will be controlled in the same engine, the bullets fired by the units will be moved into their own engine and controlled from there. First let’s create a “blueprint” for the shots as well (yes an Interface).

package interfaces
{
	import units.AUnit;

	public interface IShot
	{
		// How will we check the collision? Is it a big radius or just a point check?
		function checkUnitCollision():IUnit;
		function checkStaticCollision():void;

		// What happens if the shot hits something (damage? explosions?)
		// returns TRUE if shot will be removed.
		function onUnitCollision(unit:AUnit):Boolean; 

		// What happens if the shot hits something static in the world (like a wall or other obstacle)
		// returns TRUE if shot will be removed.
		function onStaticCollision():Boolean;

		// update movement, rotation, scale, animation etc
		function transform():void;
	}
}

Now we’re getting used to the above view so with a little time looking at the code I believe that in the end you could tell me that the shots flying around (or behaving in other ways) will have a few basic functions that will be called apon. checkUnitCollision() checkStaticCollision() onUnitCollision()  onStaticCollision() and transform().  Good. I don’t even care about creating a real implemented class of this interface, instead I want to start with the whole shotEngine that will control all shots.

I think we will take this class in parts as it might contain a few new things to the new actionscript coder. First you can start with creating a new folder besides the rest of the folders and name it “engine“. And then create a new class starting like this:

package engine
{
	import interfaces.IShot;

	import units.AUnit;

	public class ShotEngine
	{

		static private var instance:ShotEngine
		private var aShots:Array

		// ************ SINGLETON CLASS *************
		public function ShotEngine()
		{
			init()
		}

		public static function getInstance():ShotEngine
		{
			if (ShotEngine.instance == null)
			{
				ShotEngine.instance = new ShotEngine();
			}
			return ShotEngine.instance;
		}

For you who are familiar with these kinds of Singleton-classes, skip this section. For you who is not:   “WHOOOOAA!!” WTF was that??

Above is my favourite code experience of the year (yes I’m new to this as well). I’ve always had problems with the whole capsulating thing when it comes to OOP as I just don’t get how people work with global variables. I always found myself coding in a small component class deep down in a hierachy tree and suddenly need an instance of a class that’s in a toal other place, unreachable for me. The quick, dirty solution back then was to make more and more variables public and static so I could reach them from wherever I wanted to in the project. Not that OOP’ish… right.

The wonderful solution is a class called a Singleton-class. With this type of class, you can create one and only one single instance. Whenever you try to create another one you will only recieve the same instance you created from the start and it will contain the same variables and data as that first instance has. If you look at the code above you will see that it has a function called getInstance()

To use a singleton class, ALWAYS call the getInstance() function to get the instance of the class. Never ever create a new instance using the constructorname. Always call getInstance(). This way you assure yourself that you will have only one single instance of the class and in this way you can have access to the same data and methods wherever you need in a project.

Another very important thing is that a lot of classes in a gameproject can only have one single instance! You maybe want to have only one gameengines running at the same time.Noramlly you want to use only one keyboard. Only one HUD? One highscorelist, one onlineLobby etc etc.  There are ways to control that the constructor cannot be directly called apon but I won’t bring that up here. Lets focus on our class instead. Continue….

        private function init()
        {
            aShots = new Array()
        }

        public function addShot(shot:IShot)
        {
            //Add a new shot into the shotlist
            aShots.push(shot);

            // code to put shot in the 3D scene will be implanted here

        }

        public function updateShots():void
        {
            var tempShot:IShot
            var tempUnit:AUnit
            var flagDelete:Boolean

            for (var i:int = aShots.length-1 ; i>-1 ; i--)
            {
                flagDelete = false    // reseting deleteflag.
                tempShot = aShots[i]

                // first make the shot move/rotate/animate/beam...
                tempShot.transform()

                // is it hitting anyone or anything?
                tempUnit = tempShot.checkUnitCollision()
                if (tempUnit != null)
                {
                    // returning 'TRUE' if that specific shot wants to remove itself on impact
                    flagDelete = tempShot.onUnitCollision(tempUnit);       
                }
                if (tempShot.checkStaticCollision()==true)
                {
                    // returning 'TRUE' if that specific shot wants to remove itself on impact
                    flagDelete = tempShot.onStaticCollision();
                }

                if (flagDelete == true)
                {
                    // code will be implanted here to remove the visual shot from the 3D scene
                    aShots.splice(i,1) // removing shot from the shot list.
                }
            }
        }
    }
}

This “engine” will handle all shots that are flying around on stage, update them, check if they hit things and then remove them on collision if they are coded that way( some shots, a lightingcloud for example, may not want to be removed on impact but draw damage over time as the unit stays in the cloud).
So, here you go. Another post without anything happening on the scene ;) remember, the more boring code we get done underneath, the faster the progress will get later on. Next post I promise we must create something visual. Like.. hmm, a gun?





The importance of being lazy!

29 01 2009

I will soon code a LOT, actually I’ve started already behind this scene but before I make it official and show it all to you I want to pull the breaks and look in the rear window so I got all of you with me. Why’s that? Because if you don’t get the structure that’s in my head, a big part of the next upcoming code will be just a copy and paste experience and you’ll probably learn nothing so let’s take a look and let me explain some things for you. (naah you’re all smart, I’m just repeating it to understand it myself!)

Lets start with an Image:

classstructure

If we start from the bottom we have actually already created some of these “components”. The interesting thing as that all the words down there but “MESH” starts with an ‘I’. It’s because we are focusing the Interface of that component. Creating an interface makes it so much easier to code a bigger project as I don’t have to worry about how many different “transformers” I need to make or how they will be implanted. I don’t even have to create fully functional classes. This is called to “code towards the interface”. For OOP-experienced coders this is basic material but somehow Actionscript has attracted a lot of designers into the coding world and haven’t until AS3 really faced this way of programming.

So, now lets say I create a lot of controllers, transformers, weapons and shots (which will be the physical ‘bullet’ fired from the gun) I can now extend the AUnit (abstract class) into a unique unit, eg. Defender and place one of each component types in there.

As AUnit now already have the public function transformUnit() and also checkCollisions() it means that I can have as many units on the scene as I want to, looking different, behaving differntly, is controlled differently but still will be exactly the same to handle for the main core engine. Eg. Lets create 3 different units:

var arUnits:Array = new Array()
var player:AUnit = new Defender()
var computer:AUnit = new Tank()
var LANgamer:AUnit = new Soldier()

arUnits.push(player)
arUnits.push(computer)
arUnits.push(LANgamer)

for each(tempUnit:AUnit in arUnits)
{
	tempUnit.transformUnit()
	tempUnit.checkCollisions()
}

This simple code above creates 3 different units but they are all typed AUnit (!) this means we can treat them exactly the same and loop through them but they will react differently depending on which components they have inside them. Great!  I don’t have to code a loop for each unit! I don’t have to code the management for each controller, nor for each weapon.  I just code how they will behave. Now that I feel that I’ve sorted this out a little more I will start working on those weapons and clean up the previous code so we can focus on the fun part in here.





And the game so far…

28 01 2009

Here is how far we’ve come on these first posts. Remember that a lot of our work has been about seting up a good foundation to easily built new units later on, so yes, it’s a lot of code for maybe not that much of a result so far, but still it works like that infamous charm :)
http://www.solodev.eu/archon2160/DefenderTest.html