I try to design a cocos2d game that with a big world. The wolrd tiled map is very big, maybe 20 ipad screen sizes. I want to know how to load CCTMXTiledMap into screen? If I directly add it to screen, will it use too much memory? If so, is there a solution to solve this problem?
The memory usage of the tilemap depends on the size of the tiles and how many of the tiles need to be converted to sprites, for example if you want to run animate them.
Assuming your tiles are 32x32 pixels in size. 20 times iPad dimensions means 20.480x15.360 points. Divided by 32 gives you a tile size of the map of 640x480 tiles, or 307.200 tiles total. Assuming that each tile uses 64 Bytes memory (in an older cocos2d version it was less than 64 bytes) your map ends up using almost 19 MB of memory. That's not even counting the textures.
Now for every tile that you address via the CCSprite interface, for example by changing one of the sprite properties or running actions on it, cocos2d will convert that tile to a regular CCSprite. Each CCSprite object uses around 420 Bytes last time I checked. So if you were to change the color property of each tile thus converting all tiles to CCSprite objects, the tilemap would consume 123 MB of memory. Again, not including textures.
You could try the Tilemap renderer in KoboldTouch. It can handle very large tilemaps (millions of tiles, ie 4000x4000 tiles) and renders it at 60 fps.
If you try to load all the tiles at one, it will definitely occupy too much memory.
Have a look at this tutorial about CCTMXTilesMap.
Related
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 am animating some frames of a monster jumping and swinging a sword, and the frames are such that the width gets bigger or smaller as he swings the sword (the monster standing is 500 width, but his sword, fully extended to the left, adds another 200 width, thus he varies from 500 to 700 or more in width)
I originally took each frame, which is on a transparent background, and used the Photoshop magic wand tool to select just the monster. I then saved these frames like that, and when I used them to animate, the monster warped and changed sizes (it looked bad).
The original frames had a large 1000 x 1000 transparent background surrounding him, and as a result it always kept him "bound" so that it never warped.
My question is what is a good way to create frames of animation where the sprite inside might change size or width as he's moving so that there is no warping?
If I have to use a large border of transparent pixels, is that the recommended approach? I'm noticing that for my animation, each monster takes up about 3 - 5MB. I plan on potentially having a lot of these people ultimately, so i'm wondering if this is the best approach (using large 900 x 900 images all the time, plus I'll be using more for 2x and 1x). So all of this seems like it could spiral out of control to 4 or 5GB.
What are other people doing when making animations that require different poses and positions? Just fixing the frames with borders that are as small as possible?
Thanks!
You should probably change the approach to animation and use inverse kinematics instead. Take a look at this and Ray's tutorial.
I have a texture which I use as a texture map. Its a 2048 by 2048 texture divided in squares of 256 pixels each. So I have 64 "slots". This map can be empty, partly filled or full. On screen I am drawing simple squares with a slot of the sprite map each.
The problem is that I have to update this map from time to time when the asset for the slot becomes available. These assets are being downloaded from the internet but the initial information arrives in advance so I can tell how many slots I will use and see the local storage to check which ones are already available to be drawn at the start.
For example. My info says there will be 10 squares, from these 5 are available locally so when the sprite map is initialized these squares are already filled and ready to be drawn. On the screen I will show 10 squares. 5 of them will have the image stored in the texture map for those slots, the remaining 5 are drawn with a temporal image. As a new asset for a slot is downloaded I want to update my sprite map (which is bound and used for drawing) with the new corresponding texture, after the draw is finished and the sprite map has been updated I set up a flag which tells OpenGL that it should start drawing with that slot instead of the temporal image.
From what I have read, there are 3 ways to update a sprite map.
1) Upload a new one with glTextImage2D: I am currently using this approach. I will create another updater texture and then simply swap it. But i frequently run into memory warnings.
2) Modify the texture with glTextSubImage2D: I cant get this to work, I keep getting memory access errors or black textures. I believe its either because the thread is not the same or I am accessing a texture in use.
3) Use Frame Buffer Objects: I could try this but I am not certain if i can Draw on my texturebuffer while it is already being used.
What is the correct way of solving this?
This is meant to be used on an iPhone so resources are limited.
Edit: I found this post which talks about something related here.
Unfortunately I dont think its focused on modifying a texture that is currently being used.
the thread is not the same
OpenGL-ES API is absolutely not multi-threaded. Update your texture from main thread.
Because your texture must be uploaded on gpu, glTextSubImage2D is the fastest and simplest path. Keep this direction :)
Render on a Frame Buffer (attached on your texture) is very fast for rendering data which are already on gpu. (not your case). And yes you can draw on a frame buffer bound to a texture (= a frame buffer which use the texture as color attachment).
Just one contrain: You can't read and write the same texture in one draw call (The texture attached to the current frame buffer can't be bound to a texture unit)
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.
Im starting with XNA and i need an advice about the following.
I have a .jpg file with my space ship game background with the following size:
width: 5000px
height: 4800px
When i try to load the texture i get the following error:
Texture width or height is larger than the device supports
What is the most used technique to move the background at the same time that your ship is moving?
Thanks a lot.
Kind Regards.
Josema.
One way would be to separate your image into smaller tiles and draw the visible ones.
However this technique suffers from a problem when bilinear sampling is used, because the colors bleeds from the one side of the texture to the other. You can probably compensate by disabling texture WRAP sampling or by grabbing a single of pixels from the tiles next to.
For example if you want 256x256 textures, you would only display 255x255 tiles, because one line (right and bottom) is a copy from the tiles next to it.
Hope it makes sense, otherwise I'll have to paint a picture :-)
The texture limit is determined by graphics card, I believe.
You want to break the texture down to smaller images.
Try something like this. He's tiling a simple 40x40, but you might use it a a guideline on how to tile yours.
http://forums.xna.com/forums/p/19835/103704.aspx
To move the background at the same time that your ship is moving you can implement a camera.
The following links might help-
http://adambruenderman.wordpress.com/2011/04/05/create-a-2d-camera-in-xna-gs-4-0/
http://www.dreamincode.net/forums/topic/237979-2d-camera-in-xna/