I am working on a game where I need to create an enormous "world" over which a rocket ship flies. On this world, I have to programmatically generate various simple background elements. There needs to be a record of the path, so I can't use parallax effects to give the feeling of motion.
When I create the background elements using SKShapeNode and SKLabelNode objects, I get terrible performance, because I literally have to add thousands of these nodes.
Is there a way to draw text and lines directly onto a sprite object?
Related
I've seen that texture atlases are used for animations, but would it be appropriate to use for storing UI elements or items that are unrelated?
Short answer is yes, it can be appropriate. You can put them in a texture atlas if they are related UI elements.
From Apple's Documentation:
Using Texture Atlases to Collect Related Art Assets
Art assets stored in your app bundle aren’t always unrelated images. Sometimes they are collections of images that are being used together for the same sprite. For example, here are a few common collections of art assets:
Animation frames for a character
Terrain tiles used to create a game level or puzzle
Images used for user interface controls, such as buttons, switches,
and sliders
If each texture is treated as a separate object, then Sprite Kit and the graphics hardware must work harder to render scenes—and your game’s performance might suffer. Specifically, Sprite Kit must make at least one drawing pass per texture. To avoid making multiple drawing passes, Sprite Kit uses texture atlases to collect related images together. You specify which assets should be collected together, and Xcode builds a texture atlas automatically. Then, when your game loads the texture atlas, Sprite Kit manages all the images inside the atlas as if they were a single texture. You continue to use SKTexture objects to access the elements contained in the atlas.
I am working on a tilemap based game in cocos2d in which the player moves in four directions and I have used four images for the movement of player for example left,right,top and down. My problem is that when my background map change its position or move to other position then my sprite does not change its position. Can anyone tell me how to move a sprite with the movement of background.
Use a CCNode to contain both the background and the sprites for your players. Instead of moving the background, move that node.
There are a couple of ways to handle tilemap based games, and neither of them are very convenient. One way is to leave your character in the center of the screen at all times and move the background underneath it. If your character moves 'right', you simply slide the background to the left, and vice versa. This will give the illusion that the character moves around the map, when in reality it remains centered. Under this paradigm you must remember to convert all detection / collisions into the world's space, and not just the screen space. If you don't convert everything, then your 'range' of collision / detection is limited to the size of the screen.
The second method is to pan the camera over the world. You still keep the character in the middle of the screen, but it actually moves around in the world, and the camera follows. This makes the most intuitive sense to me because it allows you to view the game world as you see the real world. It is also much easier to deal with collisions because the position of the character and the world 'just work' and don't have to be converted. The downside here is that Cocos2D doesn't make it easy to use CCCamera, and the documentation is a little thin in that respect.
In your particular case, it sounds like you have a CCLayer problem. If your character is inside the layer you are moving, it will indeed remain in the same place relative to the map (as you are describing). Instead, float the character in a different layer on top of the map.
You could use a scrolling Parallex and then add the sprite onto the same layer as the background. They will move together.
Developing an iPhone game with Cocos2d-iphone. I have a huge sprite and I want to apply a CCLiquid (or any other liquid-wave-like effect) on it.
However, the image is huge, so it consumes a lot of memory (without mentioning I have many other big elements during gameplay).
Well, I figured I could try to "only apply the liquid effect on the area that is visible by the player" (dimensions of such area being 480x320). That could help a lot.
I already got a CGRect representing the area of the CCSprite that should be affected. However, how would I actually apply the effect only within such area? Any ideas?
You could manually create a CCSprite from a sprite frame and set the boundaries of that frame to your CGRect. Then use the effect on this resulting CCSprite. Essentially, your original CCSprite image would act like a larger texture atlas form which you are specifying a small portion of that image to be the actual frame of your sprite. If you layered this new copied sprite on top of your main, larger one in the exact position, it would appear to be part of that larger sprite, but only the small CGRect portion would be affected by your code.
I'm making a game using UIView.
I use a large (8192x8192) UIView as the map area, (the game is birds-eye-view) with a UIImageView stretched across it displaying a grass texture.
This uses heaps of memory, doesn't run on older devices and nearly crashes Xcode whenever I try to edit it...
Is there an alternate method of creating a 8192x8192 map, but without being laggy?
If it's possible to tile your graphics, something involving CATiledLayer would probably be a good fit. CATiledLayer allows you to provide only the images that are necessary to display the currently viewable area of the view (just like Maps does).
Here is some example code for displaying a large PDF.
I would like to create a custom NSView that takes a layered approach to painting. I imagine the majority of the layers would be the same width and height as the backing view.
Is it appropriate to use the Core Animation classes like CALayer for this task, even though I don't expect to need much animation? Is there a more appropriate approach?
To clarify, the view is not meant to be like a canvas in a Photoshop-like application. It more of a data display that should allow for user interaction (selecting, moving, scrolling, etc.)
If it's display and layout you're after, I'd say that a CALayer-based architecture is a good choice. For the open source Core Plot framework, we construct all of our graphs and plot elements out of CALayers, and organize them in a regular hierarchy. CALayers are lightweight and use almost identical APIs between Mac and iPhone. They can even be made to respond to touch or mouse events.
For another example of a CALayer-based user interface, my iPhone application's entire equation entry interface is composed of CALayers, including the menu that slides up from below. Performance is slightly better than that of my previous UIView-based implementation, but the same code also works within my preliminary desktop version of the application.
For a drawing program, I would imagine it would be important to hold a buffer of the bitmap data. The only issue with using a CALayer is that the contents property is a CGImageRef. To turn that back into a graphics context for doing further drawing can be a bit of a pain. You'd have to initialize a new context, draw the bitmap data into it, then do whatever drawing operations you wanted to do, and finally turn that back into a CGImageRef. You probably wouldn't be able to avoid doing a number of pretty large memory allocations, which is virtually guaranteed to slow your program way down.
I would consider holding an off-screen buffer for each layer. Take a look at the Quartz CGLayerRef object. I think it probably does what you want to do: it's an off-screen buffer that holds things you might want to draw repeatedly. You can also quickly get a CGContextRef whenever you need it so you can do additional drawing. And you can always use that CGContextRef with NSGraphicsContext if you want to use Cocoa drawing methods.