How to correctly implement the blocks in the drawing view, so that when they could cut the line in two parts. Using UIImageView or UIImage?
After the cut blocks should fall under the influence of physics.
First, how many cuts could happen in total? How many independent pieces of block could result? 10? 100? Before implementing any of these, test moving that number of objects around on an iPhone or iPod touch. Just because it works on the simulator does not mean it will be fast enough on the actual device.
Second, as already noted, there are libraries for game graphics and physics that may do a lot of the work for you. Cocos2D appears to be a popular option, combining OpenGL drawing with relatively easy access to physics libraries.
Anyway, to do your own drawing, here are the choices:
Move all the graphics into OpenGL. This should not be undertaken lightly - you lose a lot of the ease of working in Cocoa Touch. You also have maximum control over your graphics and animation, and can achieve the smoothest performance if you take the time to optimise it.
Have a single UIView, adding CALayer sublayers to its main layer for every independent block. CALayers are designed for rapid moving and compositing. However, if you're running a physics simulation, your first step will be to remove their animation behavior. This tutorial series may be useful.
Have a separate UIView for each block. This will have similar performance to using CALayers, as UIViews are actually drawn with CALayer. This option will use up more memory, (you have at least as many layers and more views than before), but you have all of the power of CALayers plus a few drawing options that are easier on views.
Have a single UIView, and draw every block during its drawRect method. This may look easy to implement, but it will almost certainly be too slow.
If at all possible, test each of these. Before you continue with the cutting and physics parts, how many blocks can you animate across the screen before it slows down too far? Can you make a game with that Remember that your physics system will slow the game down when it does work.
Related
I am pretty new to making games, but I am pretty familiar with programing iOS. I am creating a shape matching game, so there would be an array of different shapes and the user would drag the shape to the correct corresponding shape if they get it right it would stay and if they get it wrong it would shoot back. Now my question is would that be easier using cocso2d or any game engine or would it be just as easy not using one, just using a touch event?
Since the game you are describing is not graphically intense - I would recommend using UIKit. Couple of reasons why I would use UIKit over cocos2d:
Interface builder / Storyboards are awesome. You can lay out your
screens and game elements on screen. (I know tools exist to do this
using cocos like CocosBuilder, but IMO they just don't compare to
working directly in XCode)
UIKit animations couldn't be easier and you can do some pretty powerful things with minimal code.
You have direct access elements such as UITableView, UICollectionView, UIScrollView, etc. There are cocos nodes that mimic these, but they don't match up in terms of response and behavior.
For more graphically intense games I would still use cocos2d hands down. Some scenarios when you would use it:
You have a large number of sprites with a large number of animations (opengl is fast)
You want to use opengl based effects like particles, lighting, etc.
You need a physics engine
You want to work off a prebuilt game engine (there are tons such as levelsvg, kobold2d, line starter kit, etc)
Hope this helps you.
What I am trying to do is to have many small rectangles on the screen (up to several thousand) which move randomly.
I have the mechanics behind this figured out (in terms of determining the coordinates for the movement), but I can't figure out the best way to draw the shapes or model their movement.
A couple strategies I have tried have been, first, to subclass NSView (this is on the Mac) and create thousands of these. I then change their drawRect: function in order to draw a square inside of themselves. Then it is pretty simple to just change their locations to move them around. However, with several thousand allocated instances of these, performance is obviously terrible.
I tried a less object-oriented route also, just using NSRectFill to draw the thousands of rectangles. However, I had trouble implementing the movement I needed with this, though it was blazing fast.
Does anyone have any suggestions on how I could successfully create this animation?
Layers and Core Animation are the best approach for the platform.
Several thousand rectangles may be too much for CoreAnimation. You should consider using OpenGL.
I'm developing an iPhone Cocos2D game and reading about optimization. some say use spritesheet whenever possible. others say use atlassprite whenever possible and others say sprite is fine.
I don't get the "whenever possible", when each one can and can't be used?
Also what is the best case for each type?
My game will typically use 100 sprites in a grid, with about 5 types of sprites and some other single sprites. What is the best setup for that? guidelines for deciding for general cases will help too.
Here's what you need to know about spritesheets vs. sprites, generally.
A spritesheet is just a bunch of images put together onto one big image, and then there will be a separate file for image location data (i.e. image 1 starts at coordinate 0,0 with a size of 100,100, image 2 starts at coordinate 100,0, etc).
The advantage here is that loading textures (sprites) is a pretty I/O and memory-alloc intensive operation. If you're trying to do this continually in your game, you may get lags.
The second advantage is memory optimization. If you're using transparent PNGs for your images, there may be a lot of blank pixels -- and you can remove those and "pack" your texture sizes way down than if you used individual images. Good for both space & memory concerns. (TexturePacker is the tool I use for the latter).
So, generally, I'd say it's always a good idea to use a sprite sheet, unless you have non-transparent sprites.
I have a game that's moving fewer than 10 small animated UIImageViews at once, maximum. I'm driving their animation with a CADisplay timer running at 60fps. Here is an example of how I move the views in my update method:
// for each insect in insectArray
insectView.center = insect.hitCenter // I pull a position from my model object
The graphics are 32 x 32 pixels with up to 5 animation frames each, if that helps. They have an alpha channel for transparency. I've profiled and eliminated any in-game calculations as a bottleneck. I've also made the opacity property = YES, for a very small speedup. Having the animated frames playing or not makes no difference.
The frame rates are mostly great, except on older devices like the iPhone 1G and 3G. There I get intermittent stuttering.
Before switching to OpenGL, is there any way to get a bit more performance?
I experienced the same kind of bottleneck with CoreAnimation; it is very limited in terms of system complexity that you can display with decent performance. From what I have read and discussed with others, there is no silver bullet for you (or me) there, sorry!
My usage was actually quite close to yours (no animated frames, though), and using OpenGL ES made it go from painfully sluggish to perfectly snappy, so there's hope for you!
CoreAnimation isn't designed for frame-by-frame animation, you tell it a few keyframes and times, and it will do the rest for you. Why not switch to OpenGL? You can't support the old devices forever...
I agree with FX that there is no silver bullet, but if you provided a little more code, we could make some specific suggestions. Here are a few general ones:
Don't round corners using -setCornerRadius on the UIImageView's layer. You'd never believe how much this can degrade performance
If you're using drop shadows behind your view, make sure you specify a shadow path on the layer as well.
Try turning -shouldRasterize on on the UIImageView layer: [[insectView layer] setShouldRasterize:YES];
Hate to say it, but after this, as others have said, OpenGL is the only other choice.
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.