I'm using cocos2d for the iPhone to create an infinitely scrolling horizontal tile map. To achieve this, I've generated a library of 'segments', which are basically horizontal chunks of levels that I randomly choose from and append to the end of that particular levels tile map. When tiles scroll off of the left of the screen they are removed from the layer and released. This all works fine.
My question revolves around the legitimacy of the scrolling method I've chosen. Following guidance from this article, I've been scrolling my map by updating the layers position at regular intervals (subtracting from the x axis to move the layer to the left). And while this works, I'm concerned that there's probably some finite limit to the positioning of a layer. Am I going to run into issues after a certain amount of time has passed (when the layers x-axis position is considerably large?)
Any thoughts on my approach would be appreciated.
This is a good question. What I would do is run some tests on how far you can position the layer. I placed a sprite and focused the camera to ccp(1000000000000000, 1000000000000000) with no issues.
Do you really think this would be an issue in real gameplay? Seems like it would take a very long game to reach a position like that.
Related
I need to move an image down through canvas so that its central point would be where is now its top edge. It makes some 50 points, but if I decrease y by 50, it moves to different part of the screen on devices with different screen size. I guess, it's because my main canvas is set to scale with the screen size. So I suppose I need to manually divide the number 50 by my screen height and then code to multiply by Screen.height? Isn't there a more convenient way to move UI objects?
Allow me a second question: Do you think it is even wise to make a game purely on canvas? My game is simple 2D, only slightly animated and contains many layout elements, so I decided to go for it, but I have hard time to grasp the UI position rules.
you may have the problem of the anchoring.
Unity UI totally depends on the Anchoring, if you have got right anchoring there is no issue.
For example. if you anchored something at the Center than changing left and right value moves them according to the center anchor.
for clear visualization, you can paste a screenshot of the behavior.
I got a weird one. I'm making a game that involves stacking. Player touches the screen to drop objects and they need to stack up. My scene has a container view that is 10x bigger than the screen in both dimensions.
A woodpecker periodically drifts in from the left and bumps into the stack, threatening to topple it. I make the woodpecker stick to the stack by adding a fixed joint to one of the objects in the stack, the first one it makes contact with.
Here's what's happening: the play goes along fine for a while. As the player stacks up objects, I scroll the container down so that it appears to be panning up, to follow the top of the stack. When the stack gets to about 1500 points offset, weird things start happening. When the woodpecker bumps into the left side of the stack, suddenly the whole thing explodes! The items in the stack and woodpeckers seem to have been hit by a baseball bat. They suddenly fly away at some incredible speed. There is nothing in my code that would make it do that that I know of, and nothing particular about the offset of 1500.
I've NSLogged the X and Y positions and rotations of the woodpeckers and stack items. After one of these 'explosions', I see several sprites at very high number positions (abs value), like hundreds of thousands, and they're spinning wildly (as if they had been hit with an explosions!)
This can go on for a few explosions, then, eventually the X and Y positions of 1 to 3 sprites becomes "nan". This is correlated with a drastically reduced frame rate, like down to 0.1.
There's way too much code to include, and this problem is so weird I have no idea which snippets are most relevant. If someone has an idea of how to approach debugging this, would greatly appreciate it. Or let me know which bits of code you'd like to see if needed.
I've tried removing the fixed joint. When there are no fixed joints, the problem doesn't happen. It's also worth noting, that the woodpeckers do not respond to gravity but the stack items do. I've tried changing this too, but same problem.
I'm trying to develop a scrollable tile map in Cocos2D which uses an UIPanGestureRecognizer to do the dirty work, but while developing it, stumbled upon some problems for which I would like to ask for an advice.
The basic scrolling management works fine, it's precise and accurate and works by adding the translation recognized by the pan gesture manager to the tiles of the map. The problem is that the map is large and I just draw a small viewport of it, while I want to manage it like it's scrollable without any problem.
What I was thinking about is that, as soon as a whole row or column get out of the visible screen, it is moved to the opposite side, the corresponding texture rects are updated (I'm working entirely with a CCSpriteBatchNode), so that it will continuously update the viewport to make the whole thing work. This seems fine but I've found many problems in dealing with when to move the row/column, how to keep track of this issue (eg when pan changes direction from forth to back) and many little details which make me think that I should find a better approach.
Is there a common solution to my problem? That is: managing a scrollable viewport of a tilemap which should move over the whole map so the to the end user it seems like as if the map is infinite.
Thanks in advance
I solved my issue by developing a viewport in which rows and columns are effectively moved from left side to right side and from top side to bottom side.
This is done automatically when a new column or row enters the viewport and it's made by expanding the drawn viewport over the real one by an amount which is enough to avoid any graphical issue to the user.
I need to draw the background for a 2D space scrolling shooter. I need to implement 3 layers of stars: one distant nebula (moving really slow) in the background, one layer of far away stars (moving slow) and one layer of close stars (moving normal) on top of the other two.
The way i first tried this was using 3 textures of 320 x 480 that were transparent pngs of the stars. I used GL_BLEND and SRC_ALPHA, ONE_MINUS_SRC_ALPHA.
The results were not great even on the 3GS. On the first generation devices the FPS dropped to 40..50 so i think i'm doing this the wrong way.
When i disable the GL_BLEND everything works great even on the 1st gen devices and the FPS is back to 60 again... so it's must be the fact that i'm trying to belnd large transparent textures.
The problem is i don't know how to do it some other way...
Should i draw only the first nebula like an opaque texture and then try to emulate the middle and top star layer with small points moving around the screen?
Is there any other approach on the blending issue? How can i speed up the rendering process? Is one big texture (tileset) the answer?
Please help me cuz i'm stuck here and i can't get out.
I don't know how you want your stars to look like, but you might want to try to move them from a texture to geometry by using GL_POINTS in the DrawElements or DrawArrays maybe just replace the top two layers with layers of geometry. You can manipulate the points using PointSize, PointSizePointerOES and PointParameter to modify the rendering of the points.
You might want to use multi-texturing to see if that speeds it up. Each multi-texture stage can be assigned a unique transformation matrix, so you should be able to translate each layer at different speeds.
I believe all iPhone models support two texture stages, so you should be able to combine two of your layers into a single draw call. You might still need to resort to blending for the third layer.
Also note that alpha testing could be faster than alpha blending.
Good luck!
The back nebula should definitely be opaque; everything else is getting drawn on top of it, and I assume the only thing behind it is black. Also, prideout has a point: assuming your star layers can have effectively 1-bit alpha, that's definitely something you can try. Failing that, the GL_POINTS technique Harald mentions would work as well.
I am working on a 2D scrolling game for iPhone. I have a large image background, say 480×6000 pixels, of only a part is visible (exactly one screen’s worth, 480×320 pixels). What is the best way to get such a background on the screen?
Currently I have the background split into several textures (to get around the maximum texture size limit) and draw the whole background in each frame as a textured triangle strip. The scrolling is done by translating the modelview matrix. The scissor box is set to the window size, 480×320 pixels. This is not meant to be fast, I just wanted a working code before I get to optimizing.
I thought that maybe the OpenGL implementation would be smart enough to discard the invisible portion of the background, but according to some measuring code I wrote it looks like background takes 7 ms to draw on average and 84 ms at maximum. (This is measured in the simulator.) This is about a half of the whole render loop, ie. quite slow for me.
Drawing the background should be as easy as copying some 480×320 pixels from one part of the VRAM to another, or, in other words, blazing fast. What is the best way to get closer to such performance?
That's the fast way of doing it. Things you can do to improve performance:
Try different texture-formats. Presumably the SDK docs have details on the preferred format, and presumably smaller is better.
Cull out entirely offscreen tiles yourself
Split the image into smaller textures
I'm assuming you're drawing at a 1:1 zoom-level; is that the case?
Edit: Oops. Having read your question more carefully, I have to offer another piece of advice: Timings made on the simulator are worthless.
The quick solution:
Create a geometry matrix of tiles (quads preferably) so that there is at least one row/column of off-screen tiles on all sides of the viewable area.
Map textures to all those tiles.
As soon as one tile is outside the viewable area you can release this texture and bind a new one.
Move the tiles using a modulo of the tile width and tile height as position (so that the tile will reposition itself at its starting pos when it have moved exactly one tile in length). Also remember to remap the textures during that operation. This allows you to have a very small grid/very little texture memory loaded at any given time. Which I guess is especially important in GL ES.
If you have memory to spare and are still plagued with slow load speed (although you shouldn't for that amount of textures). You could build a texture streaming engine that preloads textures into faster memory (whatever that may be on your target device) when you reach a new area. Mapping as textures will in that case go from that faster memory when needed. Just be sure that you are able to preload it without using up all memory and remember to release it dynamically when not needed.
Here is a link to a GL (not ES) tile engine. I haven't used it myself so I cannot vouch for its functionality but it might be able to help you: http://www.mesa3d.org/brianp/TR.html