Parsing TILED XML in flashpunk, can't seem to add bitmaps and shapes?


(John Andersson) #57

Because I don’t want to have to wait until I become a master programmer to finish my current game I have already spent so much time on. The only thing standing in my way of finishing this game is loading the levels. I have made everything else (the core functions of the game) work.

Oh, and also. Why the hell do the tutorial files work but not mine? They don’t have any problems with loading the png.


(John Andersson) #58

Now I don’t even get a sandbox violation.

I just get this stupid error

load tileset at ../../assets/tilesets/Dungeon1.png
load tileset at ../../assets/tilesets/Dungeon1_front.png
load tileset at ../../assets/tilesets/Dungeon1_back.png
load tileset at ../../assets/tilesets/Dungeon1_background.png
Error #2044: Unhandled IOErrorEvent:. text=Error #2035: URL Not Found.
Error #2044: Unhandled IOErrorEvent:. text=Error #2035: URL Not Found.
Error #2044: Unhandled IOErrorEvent:. text=Error #2035: URL Not Found.
Error #2044: Unhandled IOErrorEvent:. text=Error #2035: URL Not Found.

Even though the path is correct and the files are in the trusted directories


(John Andersson) #59

You know what, I’ve had enough. Anyone who can just tell me exactly what to type gets a payment through paypal.

Here is all the code:

GameWorld:

(in the begin function)

var levelstart:Level1 = new Level1();

Level1.as:

package levels.level1
{
import blocks.*;
import enemies.*;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.events.*;
import flash.events.Event;
import flash.geom.*;
import flash.geom.Point;
import flash.net.URLLoader;
import flash.net.URLRequest;
import hero.*;
import net.flashpunk.Entity;
import net.flashpunk.FP;
import net.flashpunk.graphics.Image;

public class Level1 extends Entity
{
private var xml:XML; // for storing the tmx data as xml
private var screenBitmap:Bitmap; // for drawing the map
public var screenBitmapTopLayer:Bitmap; // data of an image, for drawing the map that the character will move under

public var mapWidth:uint;
public var mapHeight:uint;
private var tileWidth:uint;
private var tileHeight:uint;

private var tileSets:Array = new Array();

private var totalTileSets:uint = 0;
private var tileSetsLoaded:uint = 0;

public var collisionTiles:Array = new Array();
private var eventLoaders:Array = new Array();

[Embed(source = "Level_1.tmx", mimeType = "application/octet-stream")] public static const LEVEL1:Class;

public function Level1()
{			
	type = "ground";

	loadXML();
}

private function loadXML():void
{
	xml = new XML(new LEVEL1);
	mapWidth = xml.attribute("width");
	mapHeight = xml.attribute("height");
	tileWidth = xml.attribute("tilewidth");
	tileHeight = xml.attribute("tileheight");

	var tilesetCounter:uint = 0;
	
	for each (var tileset:XML in xml.tileset)
	{
		var imageWidth:uint = xml.tileset.image.attribute("width")[tilesetCounter];
		var imageHeight:uint = xml.tileset.image.attribute("height")[tilesetCounter];
		var firstGid:uint = xml.tileset.attribute("firstgid")[tilesetCounter];
		var tilesetName:String = xml.tileset.attribute("name")[tilesetCounter];
		var tilesetTileWidth:uint = xml.tileset.attribute("tilewidth")[tilesetCounter];
		var tilesetTileHeight:uint = xml.tileset.attribute("tileheight")[tilesetCounter];
		var tilesetImagePath:String = xml.tileset.image.attribute("source")[tilesetCounter];
		tileSets.push(new TileSet(firstGid, tilesetName, tilesetTileWidth, tilesetTileHeight, tilesetImagePath, imageWidth, imageHeight));
	
		tilesetCounter++;
	}
	totalTileSets = tilesetCounter;

	// load images for tileset
	for (var i:int = 0; i < totalTileSets; i++)
	{
		trace("load tileset at " + tileSets[i].source);
		var loader:TileCodeEventLoader = new TileCodeEventLoader();
		loader.contentLoaderInfo.addEventListener(Event.COMPLETE, tilesLoadComplete);
		loader.tileSet = tileSets[i];
		
		var request:URLRequest = new URLRequest(tileSets[i].source); 
		loader.load(request);
		
		eventLoaders.push(loader);
	}
	screenBitmap = new Bitmap(new BitmapData(mapWidth * tileWidth, mapHeight * tileHeight, false, 0x22ffff));
	screenBitmapTopLayer = new Bitmap(new BitmapData(mapWidth * tileWidth, mapHeight * tileHeight, true, 0));
}

private function tilesLoadComplete(e:Event):void
{
	var currentTileset:TileSet = e.target.loader.tileSet;
	currentTileset.bitmapData = Bitmap(e.target.content).bitmapData;
	tileSetsLoaded++;
	
	// wait until all the tileset images are loaded before we combine them layer by layer into one bitmap
	if (tileSetsLoaded == totalTileSets)
	{
		addTileBitmapData();
	}
}

private function addTileBitmapData():void
{
	// load each layer
	for each (var layer:XML in xml.layer)
	{
		var tiles:Array = new Array();
		var tileLength:uint = 0;
		// assign the gid to each location in the layer
		for each (var tile:XML in layer.data.tile)
		{
			var gid:Number = tile.attribute("gid");
			// if gid > 0
			if (gid > 0)
			{
				tiles[tileLength] = gid;
			}
			tileLength++;
		}

		var useBitmap:BitmapData;

		var layerName:String = layer.attribute("name")[0];

		// decide where we're going to put the layer
		var layerMap:int = 0;
		switch (layerName)
		{
			case "Top": 
				layerMap = 1;
				break;
			default: 
			//trace("using base layer");
		}

		// store the gid into a 2d array
		var tileCoordinates:Array = new Array();
		for (var tileX:int = 0; tileX < mapWidth; tileX++)
		{
			tileCoordinates[tileX] = new Array();
			for (var tileY:int = 0; tileY < mapHeight; tileY++)
			{
				tileCoordinates[tileX][tileY] = tiles[(tileX + (tileY * mapWidth))];
			}
		}

		for (var spriteForX:int = 0; spriteForX < mapWidth; spriteForX++)
		{
			for (var spriteForY:int = 0; spriteForY < mapHeight; spriteForY++)
			{
				var tileGid:int = int(tileCoordinates[spriteForX][spriteForY]);
				var currentTileset:TileSet;
				// only use tiles from this tileset (we get the source image from here)
				for each (var tileset1:TileSet in tileSets)
				{
					if (tileGid >= tileset1.firstgid - 1 && tileGid <= tileset1.lastgid)
					{
						// we found the right tileset for this gid!
						currentTileset = tileset1;
						break;
					}
				}
				var destY:int = spriteForY * tileWidth;
				var destX:int = spriteForX * tileWidth;
				// basic math to find out where the tile is coming from on the source image
				tileGid -= currentTileset.firstgid - 1;
				var sourceY:int = Math.ceil(tileGid / currentTileset.tileAmountWidth) - 1;
				var sourceX:int = tileGid - (currentTileset.tileAmountWidth * sourceY) - 1;
				// copy the tile from the tileset onto our bitmap
				if (layerMap == 0)
				{
					screenBitmap.bitmapData.copyPixels(currentTileset.bitmapData, new Rectangle(sourceX * currentTileset.tileWidth, sourceY * currentTileset.tileWidth, currentTileset.tileWidth, currentTileset.tileHeight), new Point(destX, destY), null, null, true);
				}
				else if (layerMap == 1)
				{
					screenBitmapTopLayer.bitmapData.copyPixels(currentTileset.bitmapData, new Rectangle(sourceX * currentTileset.tileWidth, sourceY * currentTileset.tileWidth, currentTileset.tileWidth, currentTileset.tileHeight), new Point(destX, destY), null, null, true);
				}
			}
		}
	}

	/*for each (var objectgroup:XML in xml.objectgroup)
	{
		var objectGroup:String = objectgroup.attribute("name");
		switch (objectGroup)
		{
			case "Collision": 
				for each (var object:XML in objectgroup.object)
				{
					var rectangle:Shape = new Shape();
					rectangle.graphics.beginFill(0x0099CC, 1);
					rectangle.graphics.drawRect(0, 0, object.attribute("width"), object.attribute("height"));
					rectangle.graphics.endFill();
					rectangle.x = object.attribute("x");
					rectangle.y = object.attribute("y");
					collisionTiles.push(rectangle);
					FP.world.add(rectangle);
				}
				break;
			default: 
				trace("unrecognized object type:", objectgroup.attribute("name"));
		}
	}*/

	// load background layer
	var screenbmap:Entity = new Entity();
	screenbmap.graphic = new Image(screenBitmap);
	FP.world.add(screenbmap);

	// load top layer
	var screenbmaptoplayer:Entity = new Entity();
	screenbmaptoplayer.graphic = new Image(screenBitmapTopLayer);
	FP.world.add(screenbmaptoplayer);
}

}

}

The TMX file (called level_1.tmx) I only excluded the actual data, like "< tile gid = “blabla” > and the objects layer

<map version="1.0" orientation="orthogonal" width="32" height="9" tilewidth="120" tileheight="120">
 <tileset firstgid="106" name="Dungeon1" tilewidth="120" tileheight="120">
  <image source="../../assets/tilesets/Dungeon1.png" trans="ffffff" width="3500" height="2536"/>
 </tileset>
 <tileset firstgid="715" name="Dungeon1_front" tilewidth="120" tileheight="120">
  <image source="../../assets/tilesets/Dungeon1_front.png" trans="ffffff" width="3500" height="2536"/>
 </tileset>
 <tileset firstgid="1324" name="Dungeon1_back" tilewidth="120" tileheight="120">
  <image source="../../assets/tilesets/Dungeon1_back.png" trans="ffffff" width="3500" height="2536"/>
 </tileset>
 <tileset firstgid="1933" name="Dungeon1_BG" tilewidth="120" tileheight="120">
  <image source="../../assets/tilesets/Dungeon1_background.png" trans="ffffff" width="3500" height="2536"/>
 </tileset>
 <layer name="BG" width="32" height="9">
  <data>
etc etc```


TileSet.as:

    package levels.level1
    {
	import flash.display.BitmapData;
	
	public class TileSet 
	{
		public var firstgid:uint;
		public var lastgid:uint;
		public var name:String;
		public var tileWidth:uint;
		public var source:String;
		public var tileHeight:uint;
		public var imageWidth:uint;
		public var imageHeight:uint;
		public var bitmapData:BitmapData;
		
		public var tileAmountWidth:uint;
		
		public function TileSet(firstgid:uint, name:String, tileWidth:uint, tileHeight:uint, source:String, imageWidth:uint, imageHeight:uint) 
		{
			this.firstgid = firstgid;
			this.name = name;
			this.tileWidth = tileWidth;
			this.tileHeight = tileHeight;
			this.source = source;
			this.imageWidth = imageWidth;
			this.imageHeight = imageHeight;
			tileAmountWidth = Math.floor(imageWidth / tileWidth);
			lastgid = tileAmountWidth * Math.floor(imageHeight / tileHeight) + firstgid - 1;
		}
	}

    }

And finally TileCodeEventLoader.as:

    package  levels.level1
    {
	import flash.display.Loader;
	
	public class TileCodeEventLoader extends Loader
	{
		public var tileSet:TileSet;		
	}
    }

(billy2000) #60

Pretty late on here but i made a search on google and i found this example of code. He is using tiled and flashpunk. Give it a try and take a look on it :stuck_out_tongue: http://pastebin.com/g1GVRjky


(John Andersson) #61

But what if I don’t want to use that in the World class? I want to use Gameworld as a “hub”. I have all of the stats (xp etc) there.


(David Williams) #62

Copy the functions into your Gameworld class, then call them from your world class and have it assigned to a variable that you can access? It doesn’t seem too difficult.


(Zachary Lewis) #63

@John_Andersson1 I wanted to give this problem a shot, and it is possible to load a .tmx file in as a Tilemap.

I put my source code up in the zachwlewis/tiled-flashpunk repository for your consumption.

Additionally, here’s the actual .swf I wound up with. You can pan across the map with and .

TiledFlashpunk.swf (185.0 KB)

Study this code and use it as a reference. Feel free to ask about anything you don’t understand in the source code. I tried to document it pretty well.

Finally, if you’re super eager to throw money around, here’s a pretty good place to do it.


(John Andersson) #64

I’m gonna donate some money as soon as I get home :slight_smile: Thank you so much.

I’m gonna try it out now and see if I can make it work!! Thanks!!!


(John Andersson) #66

Sweeeet! I can actually see my map! WOO! Thank you zach. Excellent :smiley: Just one thing, every displayed tile seems to be the one to the left of the original tileset?

Changing

_map.setTile(tileX, tileY, uint(tile.@gid - 1));

to

_map.setTile(tileX, tileY, uint(tile.@gid));

fixed it, but I hope that won’t create future problems

Just a little question, if I want to spawn my hero from that TMX file (and also make every tile in a specific layer collidable as “ground”), how should I do that? Can tilemaps work with that type of information? And any special precautions I should take if I have several tilesets in one map?


(John Andersson) #67

Okay, so I’m using 3 different spritesheets (I will use 5 in the future), and they are simply the same but with different brightness, for some 3D effect. I will make them parallax differently.

Anyway, I have this code for the TMX now:

<map version="1.0" orientation="orthogonal" width="32" height="9" tilewidth="120" tileheight="120">
 <tileset firstgid="1" name="Dungeon1" tilewidth="120" tileheight="120">
  <image source="Dungeon1.png" trans="ffffff" width="3600" height="3600"/>
 </tileset>
 <tileset firstgid="901" name="Dungeon1_BG1" tilewidth="120" tileheight="120">
  <image source="Dungeon1_BG1.png" trans="ffffff" width="3600" height="3600"/>
 </tileset>
 <tileset firstgid="1801" name="Dungeon1_FG1" tilewidth="120" tileheight="120">
  <image source="Dungeon1_FG1.png" trans="ffffff" width="3600" height="3600"/>
 </tileset>
 <layer name="BG1" width="32" height="9">
  <data>
     //TILE GIDS HERE
  </data>
 </layer>
 <layer name="BG2" width="32" height="9">
  <data>
    //TILE GIDS HERE
  </data>
 </layer>
 <layer name="FG1" width="32" height="9">
  <data>
   //TILE GIDS HERE
  </data>
 </layer>
</map>```

And this code in the level loader, so I can differentiate between the different layers.

    package game_handling
    {
	//IMPORTS HERE

	public class GameWorld extends World
	{
		[Embed(source="../assets/circle_gradient2.png")] public static const SPR_LIGHT_CIRCLE_GRADIENT:Class;
		
		private var stats:HeroStats = new HeroStats();
		
		private var xpbar:XpBarGraphic = new XpBarGraphic(470, 980);
		private var xpbar_xp:XpGraphic = new XpGraphic(470, 980);
		
		private var hpglobe:HpGlobe = new HpGlobe(30, 30);
		private var hpglobe_hp:HpGlobe_HP = new HpGlobe_HP(30, 30);
		
		private var staminabar:StaminaBarGraphic = new StaminaBarGraphic(250, 30);
		private var staminabar_stamina:StaminaGraphic = new StaminaGraphic(250, 30);
		
		private var gui:HUD = new HUD();
		private var sounds:Sounds = new Sounds();
		
		public var lighting:Lighting;
		public var mouseLight:Light;
		
		private var _map_FG2:Tilemap;
		private var _map_FG1:Tilemap;
		private var _map_Ground:Tilemap;
		private var _map_BG2:Tilemap;
		private var _map_BG1:Tilemap;
			
		//Level1
		[Embed(source = "../../levels/level_1.tmx", mimeType = "application/octet-stream")] private const LEVEL1:Class;

		[Embed(source="../../levels/Dungeon1_FG1.png")]private const DUNGEON_FG:Class;
		[Embed(source="../../levels/Dungeon1.png")]private const DUNGEON_GROUND:Class;
		[Embed(source="../../levels/Dungeon1_BG1.png")]private const DUNGEON_BG:Class;

		public function GameWorld()
		{
		
		}
		
		override public function begin():void
		{
			super.begin();
			
			//var level:Level1 = Level1(add(new Level1(LEVEL_1)));
			//var levelstart:Level1 = new Level1();
			
			//Hero stats
			add(stats);
			
			//Hp and xp graphics
			add(hpglobe);
			add(hpglobe_hp);
			
			add(xpbar);
			add(xpbar_xp);
			
			add(staminabar);
			add(staminabar_stamina);
			//HUD
			add(gui);
			
			add(sounds);
		
			//Lighting
				// create new lighting
				add(lighting = new Lighting(FP.screen.width, FP.screen.height));
				
				// add lights
				/*for (var i:uint = 0; i < 50; i++)
				{
					var image:Image = new Image(FP.choose(SPR_LIGHT_SQUARE, SPR_LIGHT_CIRCLE, SPR_LIGHT_CIRCLE_GRADIENT));
					image.centerOO();
					lighting.add(new Light(FP.rand(FP.screen.width), FP.rand(FP.screen.height), image, Math.random() * 1.5 + 0.5, Math.random(), Math.random() * 100 * FP.elapsed));
				}*/
				
			//add light that follows mouse
			var image:Image = new Image(SPR_LIGHT_CIRCLE_GRADIENT);
			image.centerOO();
			mouseLight = new Light(0, 0, image, 4);
			lighting.add(mouseLight);
			
			loadLevel1();
		}
	
		override public function update():void 
		{
			super.update();
			
			mouseLight.x = mouseX;
			mouseLight.y = mouseY;
		}
		
		public function loadLevel1():void
		{
			var mapXML:XML = FP.getXML(LEVEL1);
			var mapWidth:uint = uint(mapXML.layer.@width);
			var mapHeight:uint = uint(mapXML.layer.@height);
			var tileX:uint = 0;
			var tileY:uint = 0;

			// Create a tilemap to show the level.
			// Tile size is hardcoded, but could be pulled from the XML.
			
			_map_FG2 = new Tilemap(DUNGEON_FG, mapWidth * 120, mapHeight * 120, 120, 120);
			
			_map_FG1 = new Tilemap(DUNGEON_FG, mapWidth * 120, mapHeight * 120, 120, 120);
			
			_map_Ground = new Tilemap(DUNGEON_GROUND, mapWidth * 120, mapHeight * 120, 120, 120);
			
			_map_BG2 = new Tilemap(DUNGEON_BG, mapWidth * 120, mapHeight * 120, 120, 120);
			
			_map_BG1 = new Tilemap(DUNGEON_BG, mapWidth * 120, mapHeight * 120, 120, 120);

			trace(mapXML.layer)
			// Iterate through tiles, adding them to the tilemap.
			for each (var tile:XML in mapXML.layer.data.tile)
			{
				// Once the end of the map is reached, loop back to the start.
				if (tileX >= mapWidth)
				{
					tileX = 0;
					tileY++;
				}

				// Ignore empty tiles.
				if (tile.@gid != 0)
				{
					_map_Ground.setTile(tileX, tileY, uint(tile.@gid));
				}

				// Move to the next tile.
				tileX++;
			}

			// Add the map to the world.
			addGraphic(_map);
		}
		
		//End
	}
    }


But I get this weird error:

    Error: Java heap space


I googled and found a possible reason; that there is too little allocated memory. But I have changed that in the config file for the flash player.

(Ultima2876) #68

Have you tried restarting your computer? :slight_smile:


(Zachary Lewis) #69

If your hero is a tile, you can check for his specific gid and spawn him there when you find it.

Tilemap is a graphic. It doesn’t have any collision data. I’d suggest you create an Entity with a Tilemap as its graphic and a Grid as its mask. That will link the graphic and collision in “the standard FlashPunk way.”

With multiple tile sets, I’d just make sure I’m properly tracking my gids, since Tiled uses offset values to handle multiple spritesheets. Other than that, just look through each <layer>, creating a separate Tilemap for each layer, then parallax away.

For your heap space problem, there are already a few answers to that problem on these very forums. Use the search tool at the top of the page to see if your question is answered on here before asking again and you won’t have to wait for answers.


(John Andersson) #70

It seems that the error is related to the tilemap (actually the image used for the tileset).

If I remove

addGraphic(_map_Ground);

then I get no java heap space error.

However, I still get an “invalid bitmapdata” error. It’s probably because my tileset image is 3600 x 3600. Can as3 really not handle bigger images? If it was 5150000 x 515000 then I understand, but 3600 x 3600 is nothing… Sometimes it feels like actionscript is a god damn joke

And since I’m going all rage here, why do almost all programming languages almost always have such cryptic error messages? Java heap space error? What does that even mean? Why not something like “Too big image, stupid”?

And don’t get me started on C


(John Andersson) #71

Oh by the way, since there is a limit on the image size, I have made several smaller tilesets of the original one. They all have the same brick but in a different color. So every layer in the map will use some parts of each tileset here and there.

How do I make a tilemap work with multiple tilesets? The documentation says to provide one tileset… Because it seems stupid to have several tilemaps with one tileset each instead of having one bigass tilemap with all of the tilesets. This brings me to a problem, what if the level doesn’t use a specific tileset? How do I make it only load the necessary ones? Is all of this memory efficient?

And how would I add all of this combined data in the collision entity?

I’m a bit confused on how to solve the logical problems


(John Andersson) #72

Okay, so I’ve tried working with only one tilemap (which means only one tileset and layer) to make it work before I move on to more tilesets.

This is the code for the GameWorld so far:

package game_handling
{
imports here

public class GameWorld extends World
{
	[Embed(source="../assets/circle_gradient2.png")] public static const SPR_LIGHT_CIRCLE_GRADIENT:Class;
	
	random vars here

	**public var collisionData:Grid;**
		
	//Level1
	[Embed(source = "../../levels/level_1.tmx", mimeType = "application/octet-stream")] private const LEVEL1:Class;

	[Embed(source="../../levels/Bricks1_DarkGray.png")]private const BRICKS1_DARKGRAY:Class;
	[Embed(source="../../levels/Bricks1_Gold.png")]private const BRICKS1_GOLD:Class;
	[Embed(source="../../levels/Bricks1_Ice.png")]private const BRICKS1_ICE:Class;
	[Embed(source="../../levels/Bricks1_Purple.png")]private const BRICKS1_PURPLE:Class;
	[Embed(source="../../levels/Bricks1_White.png")]private const BRICKS1_WHITE:Class;

	public function GameWorld()
	{
	
	}
	
	override public function begin():void
	{
		super.begin();
		
		//var level:Level1 = Level1(add(new Level1(LEVEL_1)));
		//var levelstart:Level1 = new Level1();
		
		//Hero stats
		add(stats);
		
		//Hp and xp graphics
		add(hpglobe);
		add(hpglobe_hp);
		
		add(xpbar);
		add(xpbar_xp);
		
		add(staminabar);
		add(staminabar_stamina);
		//HUD
		add(gui);
		
		add(sounds);
	
		//Lighting
			// create new lighting
			add(lighting = new Lighting(FP.screen.width, FP.screen.height));
			
			// add lights
			/*for (var i:uint = 0; i < 50; i++)
			{
				var image:Image = new Image(FP.choose(SPR_LIGHT_SQUARE, SPR_LIGHT_CIRCLE, SPR_LIGHT_CIRCLE_GRADIENT));
				image.centerOO();
				lighting.add(new Light(FP.rand(FP.screen.width), FP.rand(FP.screen.height), image, Math.random() * 1.5 + 0.5, Math.random(), Math.random() * 100 * FP.elapsed));
			}*/
			
		//add light that follows mouse
		var image:Image = new Image(SPR_LIGHT_CIRCLE_GRADIENT);
		image.centerOO();
		mouseLight = new Light(0, 0, image, 4);
		lighting.add(mouseLight);
		
		loadLevel1();
	}

	override public function update():void 
	{
		super.update();
		
		mouseLight.x = mouseX;
		mouseLight.y = mouseY;
	}
	
	public function loadLevel1():void
	{
		var mapXML:XML = FP.getXML(LEVEL1);
		var mapWidth:uint = uint(mapXML.layer.@width);
		var mapHeight:uint = uint(mapXML.layer.@height);
		var tileX:uint = 0;
		var tileY:uint = 0;
		collisionData = new Grid(mapWidth * 120, mapHeight * 120, 120, 120);

		// Create a tilemap to show the level.
		// Tile size is hardcoded, but could be pulled from the XML.
		_map_Ground = new Tilemap(BRICKS1_DARKGRAY, mapWidth * 120, mapHeight * 120, 120, 120);

		// Iterate through tiles, adding them to the tilemap.
		for each (var tile:XML in mapXML.layer.data.tile)
		{
			// Once the end of the map is reached, loop back to the start.
			if (tileX >= mapWidth)
			{
				tileX = 0;
				tileY++;
			}

			// Ignore empty tiles.
			if (tile.@gid != 0)
			{
				_map_Ground.setTile(tileX, tileY, uint(tile.@gid - 1));
			}
			
			var groundTiles:String = mapXML.layer.attribute("name");
			switch (groundTiles)
			{
				case "Ground":
					collisionData.setTile(tileX, tileY, true);
					
					break;
				default:
					trace("NOTHING")
			}
			
			// Move to the next tile.
			tileX++;
		}
		
		for each (var objectgroup:XML in mapXML.objectgroup) 
		{
			var objectGroup:String = objectgroup.attribute("name");
			switch(objectGroup) 
			{
				
			case "Spawn":
				for each (var object:XML in objectgroup.object) 
				{
					var objectVar:String = objectgroup.object.attribute("name");
					switch(objectVar)
					{
					case "Hero":
						FP.world.add(new Hero(new Point(int(object.@x), int(object.@y))));
						break;
						
					default:
						trace("no spawns")
					}
				}
				break;
				
			default:
				trace("unrecognized object type:", objectgroup.attribute("name"));
			}
		}

		// Add the map to the world.
		addGraphic(_map_Ground);
		
		updateCollision();
	}
	
	public function updateCollision():void
	{
		var collision_:Collision = FP.world.getInstance("collision");
		if (collision_ == null)
		{
			trace("no collision")
			FP.world.add(new Collision(0, 0, _map_Ground, collisionData))
			
		}else {
		
			trace("updating collision")
		}
	}
	
	//End
}
}

As you can see, I tried making a grid which is the same thing as the tiles from the “ground” layer (from the XML).

I also have another class that handles the collision, Collision.as:

package game_handling 
{
import net.flashpunk.Entity;
import net.flashpunk.Graphic;
import net.flashpunk.Mask;

public class Collision extends Entity 
{
	public function Collision(x:Number=0, y:Number=0, graphic:Graphic=null, mask:Mask=null) 
	{
		name = "Collision"
		type = "ground";
		super(x, y, graphic, mask);
	}
	
	override public function update():void
	{
		trace("collision is active")
	}
}
}

I’m guessing it is all working except for one thing, the collision. The hero is simply stuck in the air, as if the grid isn’t aligned to the stage. How can I make the grid visible?

Btw, the FPS is really low now… I’m gonna try and see what is causing this


(Ultima2876) #73

The maximum size of a BitmapData in Flash is 2048x2048 pixels. Why do you need a tilemap that is so huge? o_O Most other languages do not support extremely large bitmaps natively either; usually because of hardware constraints (a lot of low-end graphics cards have limits on texture size such as 1024x1024 or 2048x2048 pixels).

The java heap space error is not a compiler error. It’s a java error and it means that java ran out of memory while trying to compile; this is often a problem with your environment - try increasing java’s heap allocation size in the settings. It sometimes does this when you are working with a huge amount of assets - another fix if you have the Flash IDE is to embed your assets in an swf and access them that way (import into Flash, add to library and check ‘export for actionscript’, give the resource and name then export -> flash movie). These assets will be precompiled and shouldn’t take up memory at compile time, thus avoiding the java heap space error.

However, the heap space problem shouldn’t occur unless you’re using hundreds of megabytes of assets… at which point a bigger concern is the final compiled size of your game and distributivity. Ideally your game should be less than 5mb when complete; you never really want it to be more than 20mb.


(John Andersson) #74

Well, the tiles are 120x120…


(Ultima2876) #75

A Canvas might be a better option than a Tilemap for tiles so large. Then each tile can be its own separate Image (BitmapData).


(John Andersson) #76

Any examples of the canvas so I know how to incorporate it?


(Ultima2876) #77

It’s pretty much a regular Graphic type, except you can draw to it like a BitmapData and it supports very large sizes. So load up your tiles as Images or BitmapData, then use the Canvas’s drawGraphic or copyPixels method to draw to it!