Archive for June, 2010


Lots of changes

Welcome back, sorry if my posts have been a bit sparse, but I am currently in the process of moving to Italy. My wife is Italian, and we have decided to give life a go over there for a bit of a new adventure and all that. Consequently, while today’s update represents of lot of new features to the game engine, I don’t have time to talk about them all in detail. What I will do, is tell you what has been added, and deal with the details in later posts.

Here is the source code, and here is a simpler version where you can edit levels, but not the original source code.

Game goals

A goal has been added into the level piece vocabulary. Basically, to progress to the next level, you need to direct the player to make contact with the goal. As an added challenge, movable blocks cannot touch the goal. I also added a reset key (press “r”) in case the player gets stuck.

Multiple levels

The game engine now supports multiple levels. It is possible to put as many <level> objects into the XML file. The game will continue to move through them as the player object reaches the goal on each level.

A smarter camera

The camera is a lot smarter now. The camera moves around the level, unless the player is near the boundaries of the game world, in which case the camera stops at the edge of the world. It is much more complicated to explain than it is to just see in the example below.

The game engine (remember to double click inside the box to play)

Get Adobe Flash player

Hope you enjoy, I will be back with details on these changes as soon as I can, but I may be a bit quiet for a few weeks. See you soon.

Just a bit of fun

I got a couple of reader submissions of level designs. Obviously working with a very limited number of tiles still, but enough to have a laugh. Just remember to double click inside the flash box that you want to interact with. The controls are just the arrow keys. Make your own levels by downloading the files and editing the XML file in a text editor.

Mori

Get Adobe Flash player

Ben Sux

Get Adobe Flash player

Level overlaid with XML data

Level overlaid with XML data

What seems to be the problem

In my last post on storing level data in XML, I outlined a method for creating levels for a tile based game that would be as easy to use as opening a text editor. Unfortunately, the method required that you enter the number of rows in the level manually. I figured if I found this annoying (which I did, squinting my eyes to count each row) then I should probably fix it.

A more efficient way

When AS3 parses through XML data, it will read XML data that falls between <tags> until there are no more. This means that if each row of a level is between XML <tags>, a two dimensional array can be created with a new array being created for each row of values. Lets have a look at the XML first.

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
<!-- 	BLOCK TYPES
		1    =    Static Block
		2    =    Ramp left to right
		3    =    Ramp right to left
		4    =    Loose block
		5    =    Player
-->
<levels>
	<level>
		<title>
			Tutorial 3
		</title>
		<data>
			<r>111111111111111111111</r>
			<r>100000000000000000501</r>
			<r>100400000000000211111</r>
			<r>100400000000021111111</r>
			<r>111111300000000000001</r>
			<r>111111113000040000001</r>
			<r>100000000000040000001</r>
			<r>104000000000040000021</r>
			<r>111113000000040000211</r>
			<r>111111300000213002111</r>
			<r>111111111111111111111</r>
		</data>
	</level>
</levels>

Inside <levels> can be any number of <level> objects. Each <level> has a <title> and <data>. The <data> is then made up of any number of <r> or row objects. This method of storing the data allows easy viewing and editing of the level, whilst eliminating the need to have a separate value for the number of rows.

Parsing the XML data

The following code is take from line 55 of the Levels.as file from the game project. This is the part that deals with parsing the level data and putting it into a usable array. See code comments for details.

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
if(levelPart.name() == "data")
{
	var dataRows:XMLList = levelPart.children();
	var n:int = 0;
	var dataArray:Array = new Array(); // A temporary array to hold each level
	for each (var eachRow:XML in dataRows) //For each XML object inside the data object
	{       
                //This reg expression selects every character and number separately
		var myPattern:RegExp = /[A-Z]|[a-z]|[0-9]/g;
 
		var str:String = eachRow.text(); //Get the text from each row
		var sArray:Array = str.match(myPattern); //Match the reg expression against the text
		dataArray[n] = sArray; //For each row, create a new array in the parent array.
		n++;
	}
	obj.data = new Array();
	obj.data = dataArray; //Add the array to the object containing other level info
}
levels.push(obj); //Push the object into the global array defined on line 12

While at the moment, the level tiles are represented by the numbers 0-5, the regular expression on line 63 allows for any character a-z both lowercase and capitals, and all numbers 0-9. This should be enough for any game we want to create.

Building the level

Back in the TileGame.as, we now have a new and improved createLvl() function. Now that the level data is in 2 dimensional array, we can traverse the data with a simple nested loop.

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
private function createLvl(e:Event):void
{
        //Store the current level data in an array for easy access
	var lvlArray:Array = L.levels[lvlCurrent-1].data;	
 
	for(var i:int = 0;i<lvlArray.length;i++)
	{				
		for(var j:int = 0;j<lvlArray[i].length;j++)
		{
			switch (lvlArray[i][j]) //This is how we find each tile value
			{
                                //I only show one object's build code for clarity.
				case "1":						
					//Create Solid Block	
                                        var wallFd:b2FixtureDef = new b2FixtureDef();
					var wallSd:b2PolygonShape= new b2PolygonShape();						
					var wallBd:b2BodyDef = new b2BodyDef();
                                        //Notice I can use the i and j integers to position elements
					wallBd.position.Set(j/ m_physScale*30, i/ m_physScale*30);
					wallBd.type = b2Body.b2_staticBody;
					wallFd.friction = .9;
					wallFd.restitution = .05;
					wallFd.shape = wallSd;
					wallSd.SetAsBox(15 / m_physScale, 15 / m_physScale);						
					levelB = m_world.CreateBody(wallBd);
					levelB.CreateFixture(wallFd);					
				break;
				case "2":
					//Create Ramp left to right			
				break;
				case "3":
					//Create Ramp right to left			
				break;
				case "4":
					//Create Loose block
				break;
				case "5":
					//Create Player
				break;
			}
		}
	}
	//Once the level is built, begin running the physics engine.
	addEventListener(Event.ENTER_FRAME, run);
}

Well that’s about it. In upcoming posts I would like to start getting some custom graphics into the game and fine tuning the camera to be a little smarter. In the mean time, feel free to play around with the full source code or just the basics with the SWF and XML.

The result

Get Adobe Flash player

Powered by WordPress. Theme: Motion by 85ideas.