Hey all, I am creating a 2D tile based XNA game. Basically the character can move any direction one tile at a time. I am using the Tiled map editor: http://www.mapeditor.org/ to create my map. I have not found any good tutorials or documentation on this yet.
Here is my issue:
I am attempting to load a very large world map into my game. Each gridspace is 32x32 pixels. The map itself is 1000x1000 gridspaces. At a first glimpse, this seems bad because of the size. When I loaded this WorldMap into my game XNA threw an out of memory error because the image was too large. I feel like I am approaching this from the wrong angle. Does anyone know a better way to handle a large world map? It would be nice to only load in what the character can see, that would be way more efficient however, that does not solve my problem of loading this huge image. Another idea would be a smaller image for each area but I am not sure how to do that since it's a world. Any ideas, tips, tutorials, I am sure this is a common issue that has been solved several times using several different solutions. Thank you!
When I was creating 2d XNA game I did:
My own format of binary map file. This file contains map name, map width and height in tiles etc and map array. It was simply byte array (byte[]) where each value corresponds to tile type.
Tile type. It's just simple class with some properties: movement cost (-1 if player can't move over this tile), which types of creatures can live in this tile, tile images etc.
Tile types db. It's just xml file contains tile types.
So, when game loads a level:
Load map and find in tile type db tiles which used in this map.
Load appropriate images for this tiles. Only once. It can be reused for different tiles with same type.
Draw only visible (for player) tiles with some reserve. As example draw only screen_width/tile_size_y*2 in width and screen_height/tile_size_y*2 in height. When player moves recalc visible tiles.
Related
Over on the Apple Documents It claimes you can make an infinitely sized SKTileMap
Generating procedural game-world maps resembling natural terrain. You can create game world of infinite size by using procedural noise as its underlying representation, and manage storage and memory efficiently by creating noise maps (and their visual representations) only for the area around a player’s current position. (See the SKTileMap class.)
I can generate realistic terrain with GKNoise like the Apple Documents claim you can.
I cannot, however, make 1 giant infinitely sized SKTileMapNode it would be to intense to run on a device
The Apple Documents say to make an SKTileMapNode only around the players current position (like chunks in minecraft)
how can I achieve this in swift? my RPG needs to be infinitely sized to achieve everything I want to do with this game.
I need the "chunks" to be SKTileMapNodes because I need trees, stone, water, etc. to be added to the map so the player can interact with it.
The solution to your problem begins in making the GKNoise tileable.
You are probably using GKNoiseMap to generate them.
When you use the initializer:
let map = GKNoiseMap(_ noise: GKNoise, size: vector_double2,
origin: vector_double2, sampleCount: vector_int2, seamless: Bool)
Important: Don't forget to set the "seamless" variable to true.
That way you get a tileable map.
It looks better when you make them larger than the screen.
Let's say that a part (tileable) of the map that is your realistic terrain is going to be 2048 by 2048
One map may cover 128x128 tiles, for example. In this case each SKTile would be 16x16 pixels
You make a SKTileMap with 128x128 tiles.
Now the SKTileMap needs a background image, or the tile definitions (in this case, it is the GKNoiseMap, that you generated)
Now you can just use the same GKNoiseMap map, and place next to the first map, in any direction, containing another tile map of 128x128 tiles.
Your map is now 256x128 tiles. When the user scrolls, they can't tell where one image ends and another begins so the whole size of the map can be as large as you want, by repeating the same exercise.
It works well when you generate GKNoiseMap bigger than the screen, when you have to scroll a couple of times before the next GKNoiseMap starts. That way it doesn't get visually repetitive.
The area around "the player's position" can be one map, and then when you scroll, the map can repeat itself, saving you from loading anything else besides the map you already generated. That answers the " and manage storage and memory efficiently by creating noise maps" part of your question.
You should also be careful with Data Storage. If every SKTile needs to store variables different than what the GKNoiseMap will give you, infinite maps can be expensive.
I am making a 2d platformer and I decided to use multiple tilemapnodes as my backgrounds. Even with 1 tile map, I get these vertical or horizontal lines that appear and disappear when I'm moving the player around the screen. See image below:
My tiles are 256x256 and I'm storing them in a tileset sks file. Not exactly sure why I'm getting this or how to get rid of this and it is quite annoying. Wondering if others experience this as well.
Considering to not use the tile maps, but I would prefer to use them if I can.
Thanks for any help with this!!!
I had the same issue and was able to solve it by "extruding" the tiled image a couple pixels. This provides a little cushion of pixels to use when the floating point issue occurs instead of displaying nothing (hence the gap). This video sums it up pretty well.
Unity: extruding tile map images
If you're using TexturePacker to generate your sprite atlas' there is an option to add this automatically without having to do it to your tile images yourself.
Hope that helps!
Sort of like the "extruding" suggested by #cheaze, I simply make the tile size in the drawing code a tiny amount larger than the required tile size. This means the assets themselves do not have to be changed.
Eg. if you assets are sized 256 x 256 and all of your calculations are based on that; draw the textures as 256.02 x 256.02 pixels in size:
[SKSpriteNode spriteNodeWithTexture:texture size:CGSizeMake(256.02, 256.02)];
Only adding .02 pixel per side will overlap your tiles automatically and remove the line glitches, depending on your camera speed and frame rate.
If the problem is really bad, you can even go so far as to add half a pixel (+0.5) or an entire pixel to remove the glitches, yet the user will not be able to see the difference. (Since a one pixel difference on a retina screen is hard to distinguish).
I just made the background layer in Tiled for my map for Sprite Kit. The main layer is the background layer where the grass, dirt, water & the lot is drawn - this what the player character "walks on". This map is consisted of tiles that are 16x16 (keeping them this small for having better control over the little details during design of the map). The map it self is 100x100. So it's pretty decent size wise. I have roughly between 757-778 nodes just because of these background tiles. That's too much and I haven't even added a single tree to the second layer. Since I'm using Tiled as the map editor with JSTileMap to display it, can I just somehow export the ready background layer from Tiled into a .png file and load that into the game as 1 big picture to drop the node count to 1. Wouldn't this drastically help performance and memory? The others layers have their images spread across & there's a layer that's responsible for the boundaries. Is this a clever way of going about making the game or am I missing something? If it is, does anyone know how to export the layer into a .png file? I checked Tiled & couldn't find anything like that.
You are most definitely better off having a single PNG/node as your background. There are some benefits of doing this:
You have just one node.
You can add the node to self and place it behind the rest of the action. This way it will always be there regardless of you moving any other nodes.
In the picture below I added a background to the view and have 3 other tile layers plus 1 object layer. My node count is still substantially less than 700.
As for exporting what you already have, I don't think there's a way to save an entire tile layer as one PNG. As a hack you could take a screenshot, crop the background part and work with that.
First of all, I would like to say that I'm fairly new to AS3, so feel free to correct me when needed.
So I'm trying to create a moving background, made out of different types of isometric tiles, like a floor or a wall, disposen in a grid like fashion.
At first, I tried creating a symbol containing the floor and the wall on different frames, and alternate between the frames as needed. Then I would add multiple instances of this symbol to a container and move the container around. Quickly I realized that this probably wouldn't be an ifficient method, as confirmed by the unsmooth movement of the container. (I gave up on this method).
So I did a little digging around, and then I converted the tile symbol to a png file, created a bitmap container to where I would copyPixels from the png as many times as the map required it.
The problem now is that when I do this:
var pngBitmapData:BitmapData=new tilePng
the bitmapData height and width don't match the height and width of the actual tile. There seem to be some transparent pixels around the tile and I have no idea how to remove them. This causes the tiles to be misaligned on the background's grid, with some small empty spaces around them.
So I have a couple of questions:
Is this an effective way to build the background?
Is there a way to avoid that transparent pixels "problem" ?
Hmm, it's hard to tell without seeing your png.
Are you doing this?
var pngBitmapData:BitmapData = new tilePng();
var bmp:Bitmap = new Bitmap(pngBitmapData);
To initialize your bitmap?
Also, check the anti-aliasing on your bitmap, that could be it. I'd set it to none.
I have created a map for a level which is 1152x640px big, i have split it up into 9x5 tiles which are 128x128px big. I use these in my spritekit game to lay out the background for the level.
In the example game "Adventure" apple have provided they do the same thing with the tiles, they then use a data map to generate invisible collision walls. I'm trying to achieve the same thing but i cant figure out how to create the data map for my game map. How can this be done?
My map: http://i.stack.imgur.com/NluPJ.png
I want a data map that specifies where the walls are in my map so i can generate them in code only using that data map.
My problem is i cant figure out how to create the data map nor how they convert the coordinates from a pixel in the data map to a world point in apples example. I have searched alot on the web for an answer to this but I cant find anything.
Is this an unneccesarily complicated way to accomplish what i need? or is there any easier way to do this?
Thanks.
I believe in the Adventure game they actually just place SKSprites down onto their map with SKPhysicsBodys on them.
To do something like this you just need the frame of each wall.
You could store this in a plist as an array of dictionaries. Something like...
[
{
x: #10,
y: #100,
width: #50,
height: #200
}
]
You can the read the array and create sprites for each rect.
they place walls in the .sks file. I believe they are color sprites on transparent with physics body option checked/dynamic unchecked ect.. Each wall is uniquely sized and positioned. They were almost certainly individually placed in the .sks file one by one. this is for the swift version at least